题目:
分析:
最初我想到的是递归,为什么这题可以用递归呢?因为它的每一步都有相似的地方,比如说它的下一个落子点可以根据当前位置的nums值来得到,递归寻找后续的落子点。当有一个递归方法的传入参数为最后一个位置时,就把标志位设置为true,然后就判断标志位剪枝,没找到就通过递归继续寻找,知道所有的递归方法结束。
递归的代码:
class Solution {
boolean flag=false;
public boolean canJump(int[] nums) {
find(nums, 0);
return flag;
}
public void find(int[] nums,int cur){
if(cur==nums.length-1){
flag=true;
}else if(cur>nums.length-1||nums[cur]==0||flag==true){
return;
}else{
for(int i=nums[cur];i>0;i--){
find(nums, cur+i);
}
}
}
}
递归的缺点及改进后的思路:
很明显,这种方式类似于枚举,只要找不到目标,就会遍历所有可能情况枚举,在输入值数据复杂的情况下会超出时间限制,这不是最佳方案。需要寻找在一次遍历下解决问题的方案,题目中有这样一个信息,它说当前位置的值是可跳跃的最大长度,那么就意味着在那个最远的位置之前的区间都是可以达到的,然后如果在当前位置和这个可跳跃的最大位置之间有值可以使得nums[i]+i大于原先的最大位置,那么就更新最大位置。如果在更新中发现最大位置大于length-1,那么最后的点是可以达到的。如果出现了越不过去的0点,那么下标会在移动中超过该点,此时返回false。
改进后的代码:
public class Solution1 {
public boolean canJump(int[] nums) {
int len=0;
for(int i=0;i<nums.length;i++){
if(i>len){
return false;
}else{
len=(len>nums[i]+i)?len:nums[i]+i;
}
}
return true;
}
}