45. 跳跃游戏 II

给定一个长度为 n0 索引整数数组 nums。初始位置为 nums[0]

每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i + j] 处:

  • 0 <= j <= nums[i]
  • i + j < n

返回到达 nums[n - 1] 的最小跳跃次数。生成的测试用例可以到达 nums[n - 1]

示例 1:

1
2
3
4
输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。

示例 2:

1
2
输入: nums = [2,3,0,1,4]
输出: 2

提示:

  • 1 <= nums.length <= 10^4
  • 0 <= nums[i] <= 1000
  • 题目保证可以到达 nums[n-1]

贪心(n):记录之前能到达的最远距离,当遍历到这个最远位置时,答案+1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution {
public int jump(int[] nums) {
int n = nums.length;
int res = 0;
int curR = 0; // 已建造的桥的右端点
int nxtR = 0; // 下一座桥的右端点的最大值
for (int i = 0; i < n-1; i++) { // 只需要跳到nums[n-1],所以这里只需要 < n-1
nxtR = Math.max(nxtR, i + nums[i]);
if (i == curR) { // 到达已建造的桥的右端点
if (i == nxtR) { // 无论怎么造桥,都无法从 i 到 i+1
return -1;
}
curR = nxtR; // 造一座桥
res++;
}
}
return res;
}
}

dp(n^2)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public int jump(int[] nums) {
int len = nums.length;
int[] dp = new int[len];
Arrays.fill(dp, Integer.MAX_VALUE);
dp[0] = 0;
for (int i = 0; i < len; i++) {
for (int j = i + 1; j <= i + nums[i] && j < len; j++) {
dp[j] = Math.min(dp[j], dp[i] + 1);
}
}
return dp[len-1];
}
}