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

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

判断你是否能够到达最后一个位置。

示例 1:

输入: [2,3,1,1,4]
输出: true
解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。
示例 2:

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

感觉是一道深度遍历的问题,需要剪枝操作,如果一个点被认为不行,以后再经过这个点可以直接说不行,这样优化还是会超时。

超时
private HashSet<Integer> set=new HashSet();
public boolean canJump(int[] nums) {
    return helper(nums,0);
}
public boolean helper(int[] nums,int index){
    if(index==nums.length-1) return true;
    if(set.contains(index)) return false;
    for(int i=index+1;i<=index+nums[index];i++){
        boolean ret=helper(nums,i);
        if(ret) return true;
    }
    set.add(index);
    return false;
}

上面的解法会在某些没有解的情况下复杂度有问题,也可以用动态规划来保存每个位置可以到达的最大位置
也可以用正向贪心求出目前每次可以走出最大步数的位置。

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

答案给的思路是反过来,如果可以到达尾部,最左边的位置是多少


程浩
21 声望2 粉丝

« 上一篇
54. 螺旋矩阵
下一篇 »
56. 合并区间