题目描述
给定一个长度为 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]
。
示例 1:
输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
示例 2:
输入: nums = [2,3,0,1,4]
输出: 2
提示:
- $ 1 <= nums.length <= 10^{4} $
- $ 0 <= nums[i] <= 1000 $
- 题目保证可以到达
nums[n-1]
算法
(贪心) $O(n)$
模拟人脑思维,下一次要到的位置,必是从该位置能走到得最远。
示例:[2, 3, 1, 1, 4]
- 从下标为0的位置出发,下一次的落点有两个选择,分别是下标为1的3和下标为2的1,此时应当选择先到下标为1的3,因为下一次从下标为1的3出发能到达的距离比从下标为2的1出发能到达的距离更远。
即每一步都选择最优策略,最终保证全局最优(贪心)。
$Java$ 代码
class Solution {
public int jump(int[] nums) {
int L = nums.length, start = 0, end = 0, res = 0;
if (L <= 1) return 0;
// 最远范围还未到达终点前一直走
while (end < L - 1) {
int maxIndex = 0;
// 寻找落点范围右端点
for (int i = start; i <= end; i ++)
maxIndex = Math.max(maxIndex, i + nums[i]);
start = end + 1;
end = maxIndex;
res ++;
}
return res;
}
}