思路
一、贪心算法(推荐使用,容易理解)
首先我们要知道,本体的关键不在于在该位置要跳几步,而关键在于我们所能跳到的最远距离。
也就是我们在跳跃过程中能够涉及到的最远覆盖范围。
- 贪心关键就在于,我们每次都取得最大的跳跃步数
- 然后再这个覆盖范围中,找到可能存在的更大的覆盖范围,以此类推,直到找到最大的覆盖范围之后,判断是否已经包含了数组的最后一个下标位即可。
二、动态规划
起始这里的动态规划就类似于贪心算法,只不过是以动态规划的方式实现
- 首先定义dp数组:dp[i]就代表在i位置时能够到达的最远距离
- 初始条件:dp[0]代表第一次可以跳到的最远距离即为
nums[0]
- 状态转换方程:要不nums[i]位置为0,则最远距离就和上一个位置是相等的;要不nums[i]不为0,说明从这个位置开始还可以向前跳跃,然后判断上一个位置能到达的最远距离和现在能够到达的最远距离两者哪一个更远,就为i位置能够到达的最远位置,即
dp[i] = Math.max(dp[i - 1], i + nums[i]);
注意:在更新dp[i]时,我们要判断上一个位置能否到达i,如果能到达,才能更新dp[i] - 最后遍历dp数组,判断是否存在一个位置可以跳到最后一个下标位即可。
代码实现(java)
class Solution {
public boolean canJump(int[] nums) {
// 贪心算法(推荐)
int range = 0;
for (int i = 0; i <= range; i++) {
range = Math.max(range, i + nums[i]);
if (range >= nums.length - 1) return true;
}
return false;
// 动态规划
// int[] dp = new int[nums.length];
// dp[0] = nums[0];
// for (int i = 1; i < nums.length; i++) {
// 只有当上一个位置能够跳到i这个位置时,再能进行更新操作,如果跳不过来,则不更新
// if (dp[i - 1] >= i) {
// dp[i] = Math.max(dp[i - 1], i + nums[i]);
// }
// }
// for (int i = 0; i < dp.length; i++) {
// if (dp[i] >= nums.length - 1) return true;
// }
// return false;
}
}