45. 跳跃游戏 II

2 阅读2分钟

给定一个长度为 n 的 0 索引整数数组 nums。初始位置在下标 0。

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

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

返回到达 n - 1 的最小跳跃次数。测试用例保证可以到达 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
  • 题目保证可以到达 n - 1

🏠 生活案例:手电筒照路

想象你走在漆黑的森林里,手里拿着一个电池不耐用的手电筒:

  • 你站在原地照了一下,最远能看清 2米 外的树(end = 2)。
  • 你必须往前走。在走到这 2米 的过程中,你每走一步都继续照一下。
  • 虽然你还没走到 2米 处,但你在 1米 处发现如果在那儿照,能看到 4米 外(farthest = 4)。
  • 当你终于走到最初看清的 2米 尽头时,你不得不更换电池再照一次(steps++),而这一照,你的视野就直接覆盖到了 4米 处(end = 4)。

🔑 为什么不遍历最后一个元素?

因为题目保证能到达。当我们走到 n-2(倒数第二个)位置时,如果 i == end 触发了跳跃,那一跳的距离必然会覆盖到 n-1。如果你遍历了最后一个元素,可能会导致多算一次不必要的跳跃。


/**
 * @param {number[]} nums
 * @return {number}
 */
var jump = function(nums) {
    let n=nums.length;
    if(n==1) return 0;
    let steps=0;
    let farthest=0;
    let end=0;
    for(let i=0;i<n-1;i++){
        farthest=Math.max(farthest,i+nums[i]);
        if(i==end){
            steps=steps+1;
            end=farthest;
        }
    } 
    return steps
};

25be3f4589b4c2cdddb2181038ecae21_720.jpg image.png