先看一眼题:
思路:贪心策略,递归寻找,如果能到达最后一个数的位置,则返回true,如果对于所有的情况都达不到,则返回false
代码:
public boolean canJump(int[] nums) {
int step = 0;//step>=nums.length-1时结束,返回true
return dfs(nums,step);
}
public boolean dfs(int[] nums,int step){
if (step < nums.length - 1) {
for (int i = nums[step]; i > 0; i--) {
int newStep= step+i;
if(dfs(nums,newStep)){
return true;
}
}
return false;
}else {
return true;
}
}
提交——超出时间限制!
他倒数第二个测试用例贼长。
想不出来优化的办法,于是看了答案:
答案说要有一个标记来维护当前最远可到的距离,关键在于如何使用这个标记:
如果已知当前最远可以到的距离,那么就可以从0到该位置,看看使用哪个位置的数可以更新最远距离,这样的思路就避免了我代码中很多无用的计算量。
使用了far标记的代码如下:
public boolean canJump(int[] nums) {
int far = nums[0];
if (far == 0 && nums.length > 1)
return false;
while (far < nums.length - 1) {
//可以走1到far步
int oldFar = far;
for (int i = 1; i <= oldFar; i++) {
//走了i步以后,看看对于从i开始的位置能否更新far
if (i + nums[i] > far) {
far = i + nums[i];
}
}
if (oldFar == far)
return false;
}
return true;
}