45. 跳跃游戏 II

45. 跳跃游戏 II

✨核心逻辑

本题采用 贪心算法 的策略,在遍历过程中维护当前能跳到的最远位置:

  1. 维护边界与最远距离:使用 end 记录当前这一步跳跃能够覆盖的边界下标,使用 maxValue 记录在遍历过程中能到达的最远下标。
  2. 单步贪心:在到达当前跳跃的边界 end 之前,不断计算从当前位置出发能够跳到的最远距离,并更新 maxValue
  3. 跨越边界:当指针 i 走到边界 end 时,说明当前这一步的最优最远距离已经确定,我们必须在这里进行下一次跳跃(跳跃次数加 1),并把边界 end 更新为之前计算出的最远距离 maxValue
  4. 逐步推进:只要边界还没覆盖到数组末尾,就继续重复上述过程,最终得到的最小跳跃次数即为答案。

🔥代码实现(含详细变量注释)

class Solution {
    public int jump(int[] nums) {
        // maxValue:记录在已经遍历的范围内,当前能够到达的最远下标位置
        int maxValue = 0;
        // n:记录给定数组的长度
        int n = nums.length;
        // jump:记录到达终点所需的当前最小跳跃次数
        int jump = 0;
        // i:用于遍历数组的索引指针,从前向后扫描
        int i = 0;
        // end:记录当前这一次跳跃所能覆盖的最远边界下标(本次跳跃可达的边界)
        int end = 0;
        
        // 边界情况:如果数组长度小于等于1,说明最开始就在最后一个下标,不需要跳跃,直接返回 0
        if (n <= 1) {
            return 0;
        }
        
        // 只要当前跳跃的边界 end 还没有到达数组的最后一个下标 n-1,说明还没到终点,继续计算
        while (end < n - 1) {
            // 贪心表达式:计算从当前位置 i 出发,能够跳到的最远距离 `i + nums[i]`
            // 并与当前记录的全局最远距离 maxValue 比较,保存最大值
            maxValue = Math.max(maxValue, i + nums[i]);
            
            // 当遍历指针 i 走过了当前跳跃范围所覆盖的全部区域(到达边界)时
            if (i == end) {
                // 必须起跳,因此跳跃次数累加 1
                jump++;
                // 以本次遍历中统计出的全局最远距离 maxValue,作为下一步跳跃的新边界
                end = maxValue;
            }
            // 指针 i 加 1,继续遍历下一个元素
            i++;
        }
        
        // 当 while 循环结束时,说明已经跳到了终点,返回统计的最小跳跃次数
        return jump;
    }
}
  • ⏱️复杂度分析
    • 时间复杂度:O(N),其中 N 是数组的长度。我们只需要对数组进行一次遍历,在循环内部执行常数次操作。

    • 空间复杂度:O(1),只使用了 maxValue、n、jump、i、end 几个额外的整型变量,没有占用额外的数组空间。

🔍反思一下: