
- 动态规划
回顾动态规划一般解题要点:定义状态、状态转移方程、初始值、输出值
本题定义数组 dp[i]:到达坐标为 i 处的最小跳跃次数
初始值:dp[0] = 0,dp[1] = 1
输出值:dp[n-1]
时间复杂度:O(
)
空间复杂度:O(n)
代码如下:
public static int jump(int[] nums) {
int n = nums.length;
if (n < 2) {
return 0;
}
//定义数组,dp[i]:到达坐标为 i 处的最小跳跃次数
int[] dp = new int[n];
//初始值
dp[0] = 0;
dp[1] = 1;
for (int i = 2; i < n; i++) {
//检查能否跳过 nums[i-1],如果能,定位到能跳过的元素 index,dp[i] = dp[index] + 1
int index = check(nums, i - 1);
if (index >= 0) {
dp[i] = dp[index] + 1;
} else {
//如果不能跳过,说明前面的数最多只能跳转到 nums[i-1],想到达 nums[i] 必须再跳一次,dp[i] = dp[i-1] + 1
dp[i] = dp[i - 1] + 1;
}
}
return dp[n - 1];
}
public static int check(int[] nums, int index) {
for (int i = 0; i < index; i++) {
if (nums[i] > index - i) return i;
}
return -1;
}
- 贪心算法
在每次可跳跃边界里选择可以跳得更远的位置
定义三个变量:跳跃次数、当前跳跃次数下能到达的最远边界、当前边界实际能达到的最远位置
时间复杂度:O(n)
空间复杂度:O(1)
代码如下:
public static int jump(int[] nums) {
//三个记录:跳跃次数、当前能跳跃次数下能到达的最远边界位置、边界位置内能跳跃的最远位置(可能比当前跳跃次数多)
int steps = 0, border = 0, max = 0;
for (int i = 0; i < nums.length - 1; i++) {
//维护更新能到达的最远距离
max = Math.max(max, nums[i] + i);
//如果本次跳跃已到达边界,更新跳跃次数和边界
if (i == border) {
steps++;
border = max;
}
}
return steps;
}