首先解决两种特殊情况,长度小于2返回true;第一个元素为0返回false。
从后往前遍历,fast直接从n-3开始,slow直接从n-2开始,因为最后一个元素即使为0也不影响结果。如果nums[slow] != 0说明肯定能通过slow这个点,slow--,fast--。
如果nums[slow] == 0,需要开始判断两种情况:
1、如果nums[fast] - nums[slow] > slow - fast,说明能通过slow这个点,slow更新位置为fast的前一个位置,fast向前跳两个位置。
2、nums[fast] - nums[slow] <= slow - fast,说明不能能通过slow这个点,fast--继续判断。
循环结束后,如果slow的位置为0或者-1,说明都可以通过,返回true。(不存在0位置是0的情况,因为一开始就解决了这种特殊情况)
class Solution {
public:
bool canJump(vector<int>& nums) {
int n = nums.size();
if (n < 2)
return true;
if (nums[0] == 0)
return false;
int fast = n - 3;
int slow = n - 2;
while (fast > -1) {
if (nums[slow] != 0) {
slow--;
} else if (nums[fast] - nums[slow] > slow - fast) {
slow = --fast;
}
fast--;
}
return slow <= 0;
}
};