首页 > 试题广场 >

几步可以从头跳到尾

[编程题]几步可以从头跳到尾
  • 热度指数:8989 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给你一个长度为 n 的数组 a
ai 表示从 i 这个位置开始最多能往后跳多少格。
求从 1 开始最少需要跳几次就能到达第 n 个格子。

数据范围:
进阶: 空间复杂度 , 时间复杂度
示例1

输入

2,[1,2]

输出

1

说明

从1号格子只需要跳跃一次就能到达2号格子    
示例2

输入

3,[2,3,1]

输出

1

说明

从1号格子只需要跳一次就能直接抵达3号格子    

备注:

    //首先计算当前最远可到达位置(记为cur),如果当前位置i已经在上一个最远可到达位置(pre),
    //说明下一步一定能够到达cur,此时steps加一,同时跟新pre的值。
    //七刷,这题思路太强了
        public int Jump (int n, int[] A) {
 
        //前一个最远可到达位置
        int pre=0;
        //当前最远可到达位置
        int cur=0;
        //步数
        int steps=0;
        //因为在pre处steps就加一,所以循环只需执行到索引n-2处  ???六刷时候没搞懂为啥n-1???
        for(int i=0;i<n-1;i++){
            cur=Math.max(cur,i+A[i]);
            //如果到达前一个最远可到达位置,说明下一步就可以到当前目标位置
            if(i==pre){
                pre=cur;
                steps++;
            }
        }
        return steps;
    }

发表于 2021-10-01 23:09:12 回复(0)
贪心算法:每次取局部最优解
摘自力扣:一个记录当前位置,一个记录最远跳跃位置,一个记录跳跃次数,遍历数组(不需要遍历到最后一位,如果遍历到最后一位,那么正好跳到最后一位的时候就会多加一次跳跃次数),每当当前位置和索引i相等时(即当前位置最后一种跳法跳完时),将最远跳跃位置赋值给当前位置,跳跃次数加1;如果在索引中没找到当前位置,就说明已经跳出去了。

function Jump( n ,  A ) {
    // write code here
    let end = 0, farthest = 0,stepNum = 0,len = A.length-1
    for(let i = 0;i<len;i++){
        farthest = Math.max(farthest, i + A[i])
        if(end>=n) break
        if(end == i){
            end = farthest
            stepNum++
        }
    }
    return stepNum
}

编辑于 2021-01-25 22:04:21 回复(0)
class Solution:
    def Jump(self , n: int, A: List[int]) -> int:
        # dp[i]表示到达i点的最小步数
        dp = [0]*n
        j = 0 
        for i in range(1, n):
            # 寻找能到达i点的最小j点
            while j + A[j] < i:
                j += 1 
            # 找到j点,更新dp
            dp[i] = dp[j] + 1 
        return dp[-1]

发表于 2023-04-27 10:11:18 回复(0)
package main

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 最少需要跳跃几次能跳到末尾
 * @param n int整型 数组A的长度
 * @param A int整型一维数组 数组A
 * @return int整型
*/
func Jump( n int ,  A []int ) int {
    var pre,cur,steps int
    for i,x:=range A{
        if i==n-1{
            break
        }
        cur=max(cur,i+x)
        if pre==i{
            pre=cur
            steps++
        } 
    }
    return steps
}

func max(a,b int)int{
    if a>b{
        return a
    }
    return b
}

发表于 2023-03-07 13:01:20 回复(0)
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 最少需要跳跃几次能跳到末尾
# @param n int整型 数组A的长度
# @param A int整型一维数组 数组A
# @return int整型
#
class Solution:
    def Jump(selfnintA: List[int]) -> int:
        # write code here
        answer = 0
        maxdis = 0
        curr = 0

        for i in range(n-1):
            maxdis = max(maxdis, i + A[i])
            if curr >= n:
                break
            if i == curr:
                curr = maxdis
                answer += 1

        return answer

发表于 2022-10-17 21:12:12 回复(0)
    public int Jump (int n, int[] A) {
        // write code here
        int[] f = new int[n];
        //贪心取j
        for (int i = 0, j = 0; i < n; i++) {
            f[i] = i;
            for (; j < i; j++) {
                if (A[j] + j >= i) {
                    f[i] = Math.min(f[i], f[j] + 1);
                    break;
                }
            }
        }
        return f[n - 1];
    }
//每次的j不需要从头开始,从上次位置开始即可,因为在此之间无法到达i,就必然无法到达i+1

发表于 2022-02-20 15:40:05 回复(0)
class Solution:
    def Jump(self , n: int, A: List[int]) -> int:
        # write code here
        pre = 0#前一个最远可到达位置
        cur = 0#当前可达最远位置
        steps = 0#总步数
        for i in range(0,n):
            cur = max(cur,i+A[i])
            if(i == pre):
                pre = cur
                steps += 1
                if(pre>=n-1):
                    break
        #print(steps)
        return steps


发表于 2022-01-18 14:50:19 回复(0)
递归

#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 最少需要跳跃几次能跳到末尾
# @param n int整型 数组A的长度
# @param A int整型一维数组 数组A
# @return int整型
#
class Solution:
    def Jump(self , n: int, A: List[int]) -> int:
        # write code here
        #递归
        if n==1:
            return 1 if A[0]>1 else 0
        if len(set(A))==1 and A[0]==1:
            return n-1
        step=[]
        def jumps(i):
            if i+A[i]>=n-1:
                return step.append(1)
            else:
                v=0
                s=i
                for j in range(i+1,i+A[i]+1):
                    if A[j]-A[i]-i+j>v:
                        v=A[j]-A[i]-i+j
                        s=j
                step.append(1)
                if s+A[s]<=n-1:
                    jumps(s)
                elif s==n-1:
                    return 
                else:
                    return step.append(1)
        jumps(0)
        return sum(step)


发表于 2022-01-12 06:00:47 回复(0)
int Jump(int n, int* A, int ALen )
{
    // 1 首先从第一个数开始跳,那么可以跳的范围是由整形数和它的位置决定,
    // 2 这个范围是arr[i]+i~i,接下来在这个范围中找到能跳到最远的位置,同时储存这个数的位置
    // 3 如果这个位置超过了arr的length,那么结束,如果没有利用存储的这个数的位置重复第二个步骤
    int nowmax=0;//初始化 当前最大可以动的范围
    int nextmax=0;//下一步最大可以动的范围
    int count=0;//跳跃步数
    int i=0,j=0;//暂存
    int k=0;
   
    while(nowmax<n-1)//步骤3的表达
    {
        nowmax=i+A[i];
       // printf("i is %d\t",i);
          for( j=nowmax;j>i;j--)
          {
              //printf("j is%d\t",j);
              nextmax=j+A[j];
             
          if(nowmax<nextmax){
              nowmax=nextmax;
               k=j;
             // printf("k is %d\t",k);
          }
          }
          i=k;
          ++count;      
    }
   return count;  
}
发表于 2021-11-05 15:04:05 回复(0)
    int Jump(int n, vector<int>& A) {
        // write code here
        //跳跃游戏
        int curDistance=0;
        int nextDistance=0;
        int res=0;
        for(int i=0;i<n;i++)
        {
            nextDistance=max(nextDistance,i+A[i]);
            if(curDistance==i)
            {
                if(curDistance==n-1)
                    break;
                else
                {
                    res++;
                    curDistance=nextDistance;
                    if(curDistance>=n-1) break;
                }
            }
        }
        return res;
    }

发表于 2021-09-21 12:44:07 回复(0)
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 最少需要跳跃几次能跳到末尾
     * @param n int整型 数组A的长度
     * @param A int整型一维数组 数组A
     * @return int整型
     */
    public int Jump (int n, int[] A) {
        // write code here
        int far = 0, count = 0, end = 0;
        for(int i = 0; i < n - 1; i ++){
            far = Math.max(far, i + A[i]);
            if(i == end){
                end = far;
                count ++;
            }
        }
        return count;
    }
}

发表于 2021-08-11 13:25:32 回复(0)
使用迭代去做。
需要跳到的位置在 数组最后一位,假设用reach表示,reach=n-1,  n为数组长度。
1. 从左往右遍历数组,找到第一个可以一步跳到reach的位置,即i+A[i]>=reach
2.将reach迭代成为上一步的位置,即reach=i
3.重复步骤1,找到第一个可以一步跳到reach的位置 ........
直到找到到位置就是第一个位置的时候截至。这样,就可以知道至少需要跳多少步才能从0 到 n-1

 class Solution {
 public:
    int Jump(int n, vector<int>& A) {
        int reach=A.size()-1;
        int steps=0;
        while(reach!=0){
            int i=0;
            while(i+A[i]<reach){ 
                i++; 
            }
            // finally, i+A[i]>=reach
            if(i==0) return steps+1;
            reach=i;
            steps+=1;
        }
        return steps;
    }
};


编辑于 2021-06-14 22:32:59 回复(2)