题目描述:

给定一个长度为 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]


与另一个(力扣55)十分相似,最短的跳跃距离,依旧是贪心,只要让位置跳的尽量远即可
真就贪心,想不到那就做不出来,无语,这种题目是真没意思,不过得注意不像上一题只要维护最大值,现在还要维护最大步长

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//代码如下
public int jump(int[] nums) {
if (nums.length == 1) return 0;
int max = 0;//当前步长能走的最大值,也即下次的步长
int step = 1;//当前步数
int stepMax = nums[0];//最大步长
for (int i = 0; i < nums.length; i++) {
//超过步长则意味着一步已经走完了
if (i > stepMax) {
step++;
stepMax = max;
max = Math.max(nums[i] + i, max);
} else {
//没走完则接着找当前步长能走的最远距离
max = Math.max(nums[i] + i, max);
}
}
return step;
}

改动态规划实现

突发奇想改了个动态规划,不过可惜,超时了,感觉有优化空间,不过懒得管了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//代码如下
public int jump2(int[] nums) {
int n = nums.length;
//横坐标索引 纵坐标剩余步数
//剩余步数其实大小也不应该是n,不过我也不知道写啥
boolean[][] dp = new boolean[n][n];

for (int i = 0; i < n; i++) {
dp[n - 1][i] = true;//到达位置,即 剩余步数为0
}
for (int step = 1; step < n; step++) {
for (int index = n - 2; index >= 0; index--) {
for (int i = 1; i <= nums[index]; i++) {
//这里应该可以优化赋值阶段的工作
if (dp[index + i][step - 1]) {
dp[index][step] = true;
break;
}
}
}
}
for (int i = 0; i < n; i++) {
if (dp[0][i]) return i;//从上到下返回第一个(最小步数)可以到达的位置
}
return -1;
}