题目介绍:
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个位置。
示例 1:
输入: [2,3,1,1,4]
输出: true
解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。
动态规划:从后往前推导,时间超出
class Solution {
public:
bool canJump(vector<int>& nums) {
vector<bool> flag(nums.size(), false);
int des = nums.size()-1;
if (des < 1) return true;
for(int i=nums.size()-1; i>=0; i--){
if (nums[i] + i >= des){
flag[i] = true;
}else{
for (int j = 1; j<=nums[i]; j++){
if ((i+j < des)&&(flag[i+j])){
flag[i] = true;
break;
}
}
}
}
return flag[0];
}
贪心:位置x可以到达,则x+nums[x]都可以到达,从左往右遍历,实时更新可到达的最大位置,大于目标位置即输出
// bool canJump(vector<int>& nums) {
// int des = nums.size()-1;
// if(des < 1) return true;
// int max_dis = nums[0];
// for(int i=0; i<des; i++){
// if (i<=max_dis){
// max_dis = max(max_dis, i+nums[i]);
// }
// if (max_dis >= des){
// return true;
// }
// // cout<<i<<" "<<max_dis<<endl;
// }
// return false;
// }
逆向判断:当遍历中,i的位置比最大可到达位置大时,无法再继续跳,则证明失败
bool canJump(vector<int>& nums) {
int max_dis = nums[0];
for(int i=0; i<nums.size(); i++){
if (i > max_dis){
return false;
}else{
max_dis = max(max_dis, i+nums[i]);
}
}
return true;
}