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 + numsi ≥ n-1,则能到达终点。

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


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

定理:

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

证明:

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

  1. k ≤ n-2(因为从 n-1 不需要再跳)
  2. 从 k 可跳到终点:k + numsk ≥ 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),只用常数空间

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

相关推荐
青石路3 小时前
记一次多JDK版本问题的排查,一坑套一坑,差点没爬上来
java
先吃饱再说4 小时前
判断回文字符串,从一行代码到双指针优化
算法
像我这样帅的人丶你还6 小时前
Java 后端详解(五):Redis 缓存
java·后端·全栈
黄敬峰7 小时前
深入理解算法核心:从递归思想、数组扁平化到快速排序
算法
plainGeekDev8 小时前
GreenDAO → Room
android·java·kotlin
小七-七牛开发者8 小时前
论文解读:DeepSeek DSpark 在真实高并发推理服务中,如何保证 Token 生成又好又快?
ai·大模型·编程·ai coding
得物技术8 小时前
从狂野代码到按目标生产:得物推荐 AI Harness 的工程化实践|AICon 演讲整理
人工智能·算法·架构
AI小老六11 小时前
SkillOpt 架构拆解:把 Skill 文本当参数,用执行轨迹训练 Agent
后端·算法·ai编程
胡萝卜术12 小时前
从“分数打架”到“排名投票”:为什么你的ChatBI必须用RRF?
算法·设计模式·面试