题目: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.
解析1:从数组的第一个位置开始往后跳,看看最终能不能跳跃到超过或等于最后一个指针的位置,代码如下:
// 时间复杂度 O(n),空间复杂度 O(1)
// 从数组的第一个位置开始往后跳
class Solution {
public:
bool canJump(vector<int>& nums) {
int reach = 0; // 最右能跳到哪里
int last_index = nums.size() - 1;
for (int i = 0; i <= reach && reach < last_index; ++i)
reach = max(reach, i + nums[i]);
return reach >= last_index;
}
};
解析2:从数组最后一个一个位置往前跳,看看能不能跳到数组的第一个位置,代码如下:
// 时间复杂度 O(n),空间复杂度 O(1)
// 从数组的最后一个位置开始往前跳
class Solution {
public:
bool canJump(vector<int>& nums) {
if (nums.empty()) return true;
// 逆向下楼梯,最左能下降到第几层
int left_most = nums.size() - 1;
for (int i = nums.size() - 2; i >= 0; --i)
if (i + nums[i] >= left_most)
left_most = i;
return left_most == 0;
}
};
解析3:用动态规划求解,令 f[i] 表示从第 0 层出发走到第 i 层时剩余的最大步数,其满足的递推公式为 f[i]=max(f[i−1],nums[i−1])+1 。如果到达数组最后一个位置处时最大剩余步数大于 0, 说明是数组最后一个位置是可以到达的,代码如下:
// 时间复杂度 O(n),空间复杂度 O(n)
// 动态规划
class Solution {
public:
bool canJump(vector<int>& nums) {
vector<int> f(nums.size(), 0);
f[0] = 0;
for (int i = 1; i < nums.size(); ++i) {
f[i] = max(f[i - 1], nums[i - 1]) - 1;
if (f[i] < 0) return false;
}
return f[nums.size() - 1] >= 0;
}
};
上面代码的思想及编写参考了网址https://github.com/soulmachine/leetcode#leetcode题解题目