给定一个长度为 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 <= 104 0 <= nums[i] <= 1000 题目保证可以到达 nums[n-1]
思路: 这个问题是一个贪心算法问题,我们的目标是找到到达数组末尾的最小跳跃次数。我们可以按照以下步骤来解决这个问题:
- 初始化:设置三个变量,step记录当前的跳跃步数,end记录当前跳跃能达到的最远位置,maxP记录在当前步数内能跳到的最远位置。
- 遍历数组:从索引0开始遍历数组nums,直到倒数第二个元素。
- 更新maxP:在每次迭代中,更新maxP为当前索引i加上可以跳的最远距离nums[i]和之前记录的maxP之间的较大值。这表示在当前步数内,我们能跳到的最远位置。
- 检查是否到达或超过end:如果当前索引i等于end,说明我们已经到达了上一次跳跃的最远位置,需要进行新的跳跃。
- 更新end和step:将end更新为maxP,表示新的最远跳跃位置,并将step加1,表示进行了一次新的跳跃。
- 结束条件:当遍历到数组的倒数第二个元素时,我们已经找到了到达数组末尾的最小跳跃次数。
时间复杂度是O(n),其中n是数组nums的长度。这是因为我们需要遍历整个数组一次。 空间复杂度是O(1),因为我们只需要几个额外的变量来记录状态,不依赖于输入数组的大小。
/**
* @param {number[]} nums
* @return {number}
*/
const jump = (nums) => {
let step = 0,
end = 0,
maxP = 0;
for (let i = 0; i < nums.length - 1; i++) {
maxP = Math.max(maxP, nums[i] + i);
if (i == end) {
end = maxP;
step++;
}
}
return step;
};