这道题的本质:最远能不能到数组最后一个元素。
可以超过但不能达不到
/**
* 自己的代码,没有找到这题本质,效率很低
* 只要能到达一个位置,它前面的位置也一定都能到达,只要遍历数组不断更新最远能访问到哪里就行了
* Runtime: 1177 ms, faster than 5.02%
* Memory Usage: 43.6 MB, less than 5.39%
*/
class Solution {
public boolean canJump(int[] nums) {
Boolean[] already = new Boolean[nums.length - 1]; // 记录已经知道的能不能访问到最后一个元素的情况,最后一个元素不用记录所以数组长度设为nums.length - 1
return helper(already, nums, 0);
}
private boolean helper(Boolean[] already, int[] nums, int idx) {
if (idx == nums.length - 1)
return true;
if (already[idx] != null)
return already[idx];
for (int i = 1; i <= nums[idx]; i++) {
if (idx + i < nums.length && helper(already, nums, idx + i)) {
return true;
}
}
already[idx] = false;
return false;
}
}
/**
* 不断更新最远的值
* Runtime: 1 ms, faster than 83.57%
* Memory Usage: 40.8 MB, less than 72.47%
*/
class Solution {
public boolean canJump(int[] nums) {
int reachable = 0;
for (int i = 0; i <= reachable && reachable < nums.length - 1; i++) {
reachable = Math.max(reachable, i + nums[i]);
}
return reachable >= nums.length - 1;
}
}
/**
* 从后向前遍历数组,只要没有0元素,当前位置往后一直可达
* 当遇到0元素,就要判断前面的元素可达长度能不能跨过这个0元素,若前面的都跨不过0元素,则数组尾不可达
* Runtime: 0 ms, faster than 100.00%
*。Memory Usage: 40.7 MB, less than 83.46%
*/
class Solution {
public boolean canJump(int[] nums) {
for (int i = nums.length - 2; i >= 0; i--) {
if (nums[i] == 0) { // 如果遇到0元素
int neededJumps = 1; // 在当前0元素,需要的jump数本来应该是1
while (nums[i] < neededJumps) { // i位置跨不过0元素
i--; // 再往前找
neededJumps++; // 需要的jump数加一
if (i < 0) // 都跨不过0元素
return false;
}
}
}
return true;
}
}