贪心局部的最优,和股票一样,维护一个最什么的值
从i=0到cover去维护就很妙,因为这样可以全覆盖【不是仅仅从一个点跳到一个点】,而且避免了回溯的尴尬。
class Solution {
public:
bool canJump(vector<int>& nums) {
int cover = 0;//覆盖max范围
for(int i = 0;i<=cover;i++){
cover = max(nums[i]+i,cover);
if(cover>=nums.size()-1){//要在for内判断,而不是for外
return true;
}
}
return false;
}
};
动态规划
class Solution {
public:
bool canJump(vector<int>& nums) {
int n = nums.size();
vector<bool> dp(n, false); // dp[i]表示从位置i可以到达最后一个位置
dp[n - 1] = true; // 最后一个位置自然是可以到达的
// 从倒数第二个位置开始,逐步判断每个位置
for (int i = n - 2; i >= 0; i--) {
// 检查当前位置能跳到的最远位置,如果可以到达最后一个位置,就设置dp[i]为true
int farthest = i + nums[i];
for (int j = i + 1; j <= min(farthest, n - 1); j++) {
if (dp[j]) {
dp[i] = true;
break; // 如果能通过当前位置跳跃到后面的一个位置就可以到达最后一个位置,直接跳出循环
}
}
}
return dp[0]; // 如果从位置0可以到达最后一个位置,返回true
}
};
回溯
class Solution {
public :
bool canJumpFromPosition(int position, vector<int>& nums,
vector<bool>& visited) {
int n = nums.size();
// 如果当前位置已经访问过了,说明已经尝试过此路径,避免重复计算
if (visited[position]) {
return false;
}
// 标记当前位置为已访问
visited[position] = true;
// 如果已经到达最后一个位置,返回true
if (position == n - 1) {
return true;
}
// 尝试从当前位置跳跃到其他位置
int farthestJump =
min(position + nums[position], n - 1); // 最远可以跳跃的位置
for (int nextPosition = position + 1; nextPosition <= farthestJump;
nextPosition++) {
if (canJumpFromPosition(nextPosition, nums, visited)) {
return true; // 如果从某个跳跃位置能够到达最后一个位置,返回true
}
}
return false; // 如果所有的跳跃都无法到达最后一个位置,返回false
}
bool canJump(vector<int>& nums) {
int n = nums.size();
vector<bool> visited(n, false); // 记录每个位置是否已经被访问过
return canJumpFromPosition(0, nums, visited); // 从起始位置开始尝试跳跃
}
};