给定一个非负整数数组,你最初位于数组的第一个位置。数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个位置。
示例 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;
}
答案给的思路是反过来,如果可以到达尾部,最左边的位置是多少
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。