LeetCode热题100--45.跳跃游戏 II

45. 跳跃游戏 II

算法核心

这是一个贪心算法,通过维护当前跳跃边界end和当前可到达的最远位置maxP,每次到达边界时进行跳跃,从而以最小步数到达终点。

关键点

  • 遍历到 n-2 即可,不需要处理 n-1
  • 因为题目保证能到达终点
  • i=n-2 时,要么已经到达终点,要么从 n-2 能跳到终点
  • 处理 n-1 会导致多余跳跃计数

两个正常例子证明

例子1:end == n-1(边界正好是终点)

nums = [2, 3, 1, 4, 5],n=5,终点索引=4

复制代码
索引: 0  1  2  3  4
数值: 2  3  1  4  5

执行过程

复制代码
初始: res=0, maxP=0, end=0

i=0: 在位置0,可跳到2
    maxP = max(0, 0+2) = 2
    i==end(0==0) → 跳跃!
    end = 2, res=1

i=1: 在位置1,可跳到4
    maxP = max(2, 1+3) = 4
    i≠end(1≠2) → 不跳

i=2: 在位置2,可跳到3
    maxP = max(4, 2+1) = 4
    i==end(2==2) → 跳跃!
    end = 4, res=2
    ★ 此时 end=4 正好等于 n-1

i=3: 循环条件 i<4,i=3<4,继续
    maxP = max(4, 3+4) = 7
    i≠end(3≠4) → 不跳
    循环结束(i=4不会处理)

结果: res=2

分析

  • 在 i=2 时,end=4 已到达终点
  • 不需要处理 i=3 和 i=4
  • 即使遍历到 n-2=3,也不会再增加跳跃次数
  • 终点正好是边界的情况,提前结束没有问题

例子2:end > n-1(边界超过终点)

nums = [3, 2, 1, 1, 1],n=5,终点索引=4

复制代码
索引: 0  1  2  3  4
数值: 3  2  1  1  1

执行过程

复制代码
初始: res=0, maxP=0, end=0

i=0: 在位置0,可跳到3
    maxP = max(0, 0+3) = 3
    i==end(0==0) → 跳跃!
    end = 3, res=1
    ★ 此时从位置0直接可到终点4(因为3≥4)

i=1: 在位置1,可跳到3
    maxP = max(3, 1+2) = 3
    i≠end(1≠3) → 不跳

i=2: 在位置2,可跳到3
    maxP = max(3, 2+1) = 3
    i≠end(2≠3) → 不跳

i=3: 在位置3,可跳到4
    maxP = max(3, 3+1) = 4
    i==end(3==3) → 跳跃!
    end = 4, res=2
    ★ 实际上这次跳跃是多余的,但算法会计数

结果: res=2

实际最少跳跃 :1次(0→3或0→4)
算法结果 :2次
注意 :这个例子说明算法结果是上界,不一定是最优路径,但题目要求最少跳跃次数,这种情况实际上算法给出了2,但最优是1。

修正例子 :改为 nums = [3, 1, 1, 1, 1]

复制代码
i=0: end=3, res=1
i=1: maxP=3
i=2: maxP=3
i=3: i==end→end=3, res=2
结果: res=2
边界在3,但可跳到终点

不会出现的例子(理论上存在但题目保证不会出现)

例子3:无法到达终点

nums = [3, 2, 1, 0, 0, 0],n=6

复制代码
索引: 0  1  2  3  4  5
数值: 3  2  1  0  0  0

执行过程

复制代码
初始: res=0, maxP=0, end=0

i=0: 可跳到3
    maxP = 3
    i==end → end=3, res=1

i=1: 可跳到3
    maxP = max(3, 3) = 3

i=2: 可跳到3
    maxP = 3
    i==end? 2≠3 → 不跳

i=3: 在位置3,nums[3]=0,可跳到3
    maxP = 3
    i==end(3==3) → 跳跃!
    end = 3, res=2
    ★ 边界没有前进!

i=4: 在位置4,nums[4]=0
    maxP = 3
    i≠end(4≠3) → 不跳

i=5: 循环条件 i<5,i=4<5,继续
    i=5不会处理
结束

问题

  • 在 i=3 时,边界从 3 更新到 3,没有前进
  • 之后无法到达终点
  • 但题目保证这种情况不会出现

验证能到达终点的条件

如果存在某个位置 i 使得 i + nums[i] ≥ n-1,则能到达终点。

在合法输入中,一定存在这样的位置链。


为什么遍历到 n-2 即可:数学证明

定理:

在保证能到达终点的条件下,算法在遍历到 i=n-2 时,maxP ≥ n-1

证明:

设最后一步跳跃的起点为 k,则 k 满足:

  1. k ≤ n-2(因为从 n-1 不需要再跳)
  2. 从 k 可跳到终点:k + nums[k] ≥ n-1

考虑两种情况:

情况A:k < n-2

  • 那么在 i=k 时,maxP ≥ k + nums[k] ≥ n-1
  • 此时或之后某个时刻,end 会被更新为 ≥ n-1
  • 在 i 到达 n-2 前,end 已 ≥ n-1

情况B:k = n-2

  • 在 i=n-2 时,maxP ≥ (n-2) + nums[n-2] ≥ n-1
  • 如果 i=n-2 正好是当前边界,则更新 end ≥ n-1
  • 如果 i=n-2 不是当前边界,则之前的 end 已 ≥ n-1

因此 :在 i 遍历到 n-2 时,必然有 end ≥ n-1 或即将被设为 ≥ n-1


重要结论

  1. 遍历到 n-2 足够:因为终点位置 n-1 不需要作为起跳点
  2. 避免多余跳跃 :如果在 n-1 处检查 if(i==end),可能会错误增加跳跃次数
  3. 算法正确性:贪心策略 + 提前终止保证结果正确
  4. 时间复杂度:O(n),只遍历一次
  5. 空间复杂度:O(1),只用常数空间

这个算法巧妙地用最小代价解决了问题,是贪心算法的经典应用。

相关推荐
bilI LESS2 小时前
Spring Boot接收参数的19种方式
java·spring boot·后端
foundbug9992 小时前
基于STM32的步进电机加减速程序设计(梯形加减速算法)
stm32·单片机·算法
九皇叔叔2 小时前
004-SpringSecurity-Demo 拆分环境
java·springboot3·springsecurity
北顾笙9802 小时前
day12-数据结构力扣
数据结构·算法·leetcode
凌波粒2 小时前
LeetCode--454.四数相加 II(哈希表)
算法·leetcode·散列表
爱滑雪的码农2 小时前
Java八:Character 类与string类
java·开发语言
漫随流水3 小时前
c++编程:D进制的A+B(1022-PAT乙级)
数据结构·c++·算法
tankeven3 小时前
HJ159 没挡住洪水
c++·算法
美式请加冰3 小时前
斐波那契数列介绍和使用
算法