1. 题目与解析
给定一个长度为 n
的 0 索引整数数组 nums
。初始位置为 nums[0]
。
每个元素 nums[i]
表示从索引 i
向前跳转的最大长度。换句话说,如果你在 nums[i]
处,你可以跳转到任意 nums[i + j]
处:
0 <= j <= nums[i]
i + j < n
返回到达 nums[n - 1]
的最小跳跃次数。生成的测试用例可以到达 nums[n - 1]
。
输入: nums = [2,3,0,1,4]
输出: 2
输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。 从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
提示:
1 <= nums.length <= 104
0 <= nums[i] <= 1000
- 题目保证可以到达
nums[n-1]
我们的目标是到达数组的最后一个位置,因此我们可以考虑最后一步跳跃前所在的位置,该位置通过跳跃能够到达最后一个位置。
求到达 nums[n - 1]
的最小跳跃次数,和跳楼梯的逻辑很像,不同一点是,在这道中,青蛙位于i位置时,可以移动到多个位置而不是1个位置,不过整体的解题思路无伤大雅,是典型的动态规划题目,dp[i]位置有可能移动到dp[i+1]到dp[i+nums[i]],状态转移的方式是加一。
需要注意的一点是,在进行状态转移遍历判断的过程中可能出现数组越界的情况,即i+nums[i]
又肯大于n
,针对这种情况,需要进行约束,不然会产生数组越界的报错,如下所示:
for (int j = i+1; j < n && j <= i+nums[i]; j++) {
dp[j] = Math.min(dp[j], dp[i]+1);
}
2. 题解
class Solution {
public int jump(int[] nums) {
int n = nums.length;
int[] dp = new int[n];
Arrays.fill(dp, Integer.MAX_VALUE);
dp[0] = 0;
for (int i = 0; i < n-1; i++) {
for (int j = i+1; j < n && j <= i+nums[i]; j++) {
dp[j] = Math.min(dp[j], dp[i]+1);
}
}
return dp[n-1];
}
}