Given an array of non-negative integers, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Determine if you are able to reach the last index.
For example:
A = [2,3,1,1,4]
, return true
.
A = [3,2,1,0,4]
, return false
.
解法一:
类似dp的思想,把那些可以到达的地方标为1。不过不考虑细节的话不能通过time test。
class Solution {
public:
bool canJump(vector<int>& nums) {
vector<int> dp(nums.size(),0);
dp[0]=1;
for(int i=0; i<nums.size(); i++){
if(dp[i]==0) continue;
for(int j=1; j<=nums[i]; j++) {
if((i+j)<nums.size()) dp[i+j]=1;
}
}
return dp.back()==1?true:false;
}
};
解法二:
考虑几点:
1) while中的for循环不能超过vector的尾部,这里step来约束。
2) 使用一个idx,表示之前最远到达的地方。如果当前的走的还不如idx远,则continue。
class Solution {
public:
bool canJump(vector<int>& nums) {
vector<int> dp(nums.size(),0);
dp[0]=1;
int i = 0;
int idx = 0;
while(i<nums.size()){
if(dp[i]==0) {i++;continue;}
if(i+nums[i]<=idx) {i++;continue;}
int step = min(nums[i],int(nums.size()-1)-i);
for(int j=1; j<=step; j++) {
if((i+j)<nums.size()) dp[i+j]=1;
}
idx = i+step;
i++;
}
return dp.back()==1?true:false;
}
};
这里的dp表示的是到当前i位置还可以往前走多少步。那么dp的表达式可以见code。如果当前的值等于0,表示不能再往前走了。dp[i]<0直接返回false,如果最后一个值大于等于0,则说明可以走到最后。
class Solution {
public:
bool canJump(vector<int>& nums) {
vector<int> dp(nums.size(),0);
int n = nums.size();
for (int i = 1; i < n; ++i) {
dp[i] = max(dp[i - 1], nums[i - 1]) - 1;
if (dp[i] < 0) return false;
}
return dp.back() >= 0;
}
};
解法四:
下面这个是O(n) time + O(1) space。maxIdx表示当前可以走到的最远的idx。如果maxIdx <i 说明i都到不了,结束循环。或者maxIdx已经可以末尾,也break。最后看maxIdx是否比n-1,即最后一个元素的index大。
class Solution {
public:
bool canJump(vector<int>& nums) {
int n = nums.size();
int maxIdx = 0;
for (int i = 0; i < n; ++i) {
if(maxIdx<i || maxIdx>=n-1) break;
maxIdx = max(maxIdx, i+nums[i]);
}
return maxIdx>=n-1;
}
};