算法思路汇总:55.跳跃游戏

358 阅读2分钟

55.跳跃游戏

「这是我参与2022首次更文挑战的第28天,活动详情查看:2022首次更文挑战」。

难度:mid,来源:力扣,类型:贪心

给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。

数组中的每个元素代表你在该位置可以跳跃的最大长度。

判断你是否能够到达最后一个下标。

示例 1:

输入:nums = [2,3,1,1,4] 输出:true 解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。

示例 2:

输入:nums = [3,2,1,0,4] 输出:false 解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标。

提示:

  1. 1 <= nums.length <= 3 * 104
  2. 0 <= nums[i] <= 105

思路:

不知道有没有朋友跟我一样,读完题目,看完例子没懂什么意思,虽然第一个例子明白,但是第二个例子啥意思,不是可以先跳1步在跳3步也能到达最后吗。所以就很迷惑。

没错,我就是个笨比:

压死你个笨比(杰尼龟)_杰尼龟_你个_压死表情

所以还是得好好读题: (圈出重点)

数组中的每个元素代表你在该位置可以跳跃的最大长度。

输入:nums = [2,3,1,1,4] 解释:可以先跳 1 步(也可以跳2步,当前元素为最大跳跃的范围),从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。

所以我们只要保证我们跳跃的最大距离能够包含当前下标的大小就行,如果我们最大距离包含了,那么我们在其范围内不管怎么选取都能到达,但是如果不能包含,那么表明我们的范围无法覆盖,也就无法走到目标地址。如果能够一直跳到最后,那就成功了。

if(i > scope) return false;
scope = Math.max(scope,nums[i]+i);

完成代码:

class Solution {
    public boolean canJump(int[] nums) {
        int n = nums.length;
        //最大范围
        int scope = 0;
        for(int i = 0; i < n; i++){
            if(i > scope) return false;
            scope = Math.max(scope,nums[i]+i);
        }
        return true;
    }
}

或者如下代码:

class Solution {
    public boolean canJump(int[] nums) {
        int n = nums.length;
        if(n == 1) return true;
        int scope = 0;
        for(int i = 0; i <= scope; i++){
            scope = Math.max(scope,nums[i]+i);
            if(scope >= n-1) return true;
        }
        return false;
    }
}