核心思路:
算出来每个位置的最远距离即可。最远距离达到尾部了就算true
举个例子:[2,1,3,2,0,0,100]
- 当下标为0,我们可以得到最远距离到下标为2的位置
- 当下标为1,我们可以得到最远距离到下标为2的位置
- 当下标为2,我们可以得到最远距离到下标为5的位置
- 当下标为3,我们可以得到最远距离到下标为5的位置
- 当下标为4,我们可以得到最远距离到下标为5的位置
- 当下标为5,我们可以得到最远距离到下标为5的位置
到最后我们也没得到一个最远距离 >= 6的位置,所以返回false
并且过程中我们还要考虑到一个断档问题:即,别说跳到终点,中间就有可能有一大堆零,跳不过去了。
所以我们的循环要一直控制在目前能跳到的最远距离范围。
c++实现
class Solution {
public:
bool canJump(vector<int>& nums) {
// write code here
if(nums.size() == 1) return true;
vector<int> dp(nums.size()-1); //dp用来记录每一步的值
dp[0] = nums[0];
int m=nums[0]; //m用来存储当前最大值
for(int i=1; i<=m && i<nums.size()-1; i++){ //注意判断条件,除了不能超过nums.size,还要小于最大距离
dp[i] = max(i+nums[i], dp[i-1]); //当前下标+能迈的步数 与 之前的最大值 相比较
if(dp[i] > m) m = dp[i]; //留存最大值
if(m >= nums.size()-1) break; //如果已经能达到终点,直接break即可
}
if(m >= nums.size()-1){
return true;
}else{
return false;
}
}
};
但是写完了以后,想了想,dp这个容器其实没有必要存在,因为dp的最后一个永远是最大值,那我们其实只需要存一个最大值就够了。
以下是优化后的代码:
c++优化版
class Solution {
public:
bool canJump(vector<int>& nums) {
// write code here
if(nums.size() == 1) return true;
int temp = nums[0];
for(int i=0; i<=temp; i++){
temp = max(i+nums[i], temp);
if(temp >= nums.size()-1) return true;
}
return false;
}
};