跳到正文
第 45 题中等

跳跃游戏 II

Jump Game II

从下标 0 跳到最后一个下标,每次最多跳 nums[i] 步,求最少跳跃次数。

在力扣中练习

题目描述

给定一个长度为 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

解题思路

主解法

贪心 · 按层扩展

当前跳数能覆盖一层,扫描这一层找出下一层的最远边界

把跳跃看成 BFS 分层:跳 0 次能到 {0},跳 1 次能到 0 能覆盖的范围,跳 2 次能到下一层……最少跳数就是第一次覆盖到终点的层数。

不需要真的建图,维护三个量即可:

  • end:当前跳数能到达的最远位置;
  • farthest:扫描当前层时,下一跳能到达的最远位置;
  • jumps:已经跳了几次。
分步图解

从下标 0 出发,跳数 0;扫描当前层能覆盖的所有位置,找出下一层最远能到哪。

nums · 蓝色是当前跳跃层能覆盖的范围
0
1
2
3
4
5
6
2
4
1
2
3
1
2
end 是当前跳数能到达的最远位置;farthest 是扫描过程中发现的下一层边界。
状态
jumps=0end=0farthest=0
1 / 4
扫描第一层 [0,2] 时不断扩展 farthest,到 end 时跳数加一并进入下一层。

遍历 0 .. n-2,不断用 i + nums[i] 更新 farthest;当 i == end 时,当前层扫描完,跳数加一,end 更新为 farthest。

分步图解

i=2,从 1 最远到 3,farthest 5 → 5;到达当前层边界,跳数 +1,下一层 end=5。

jumps
2
end
5
nums · 蓝色是当前跳跃层能覆盖的范围
0
1
2
3
4
5
6
2
4
1
2
3
1
2
i
end 是当前跳数能到达的最远位置;farthest 是扫描过程中发现的下一层边界。
状态
jumps=2end=5farthest=5
1 / 4
第二层 [3,5] 的最远覆盖是 7,超过末尾,第三跳即可到达。

自拟数组第一层覆盖到下标 2,第二层覆盖到 5,第三层越过末尾,共 3 跳。贪心之所以正确,是因为同一层内所有位置跳数相同,只需关心最远能扩到哪。

时间 O(n),空间 O(1)。

时间 O(n)空间 O(1)

易错点

  • 循环写到 n-1:最后一个位置不需要再起跳,可能多算一跳。
  • 把 end 和 farthest 混成一个变量:无法区分“当前层边界”和“下一层边界”。
  • 每次跳到当前能到的最远点:这是局部最优,但不一定保证全局最少跳数。
对照解法

动态规划 · 从每个位置更新

dp[i] 表示到达 i 的最少跳数

结果正确,但 O(n²) 且需要 O(n) 数组;贪心版把状态压成三个变量。

定义 dp[i] 为到达下标 i 的最少跳跃次数,dp[0]=0。从每个可达位置 i 出发,枚举能跳到的 i+step,用 dp[i]+1 更新它们。

这是最直观的 BFS/DP 写法,正确性很容易证明;但每个位置都可能向后枚举 nums[i] 个位置,最坏 O(n²)。

它适合用来验证贪心结果,或者在跳跃规则更复杂(例如有代价、有障碍)时作为通用解法。

  1. 1dp[0]=0,其余为无穷大。
  2. 2遍历每个位置,枚举能跳到的位置。
  3. 3用 dp[i]+1 更新目标位置。
  4. 4返回 dp[n-1]。
时间 O(n²)空间 O(n)

易错点

  • dp 初始化为 0:所有位置看起来都可达且跳数为 0。
  • 从不可达位置继续扩展:会传播错误状态。

代码与演示

主解法配有图解;对照解法用于比较思路、复杂度或实现方式。

演示输入nums = [2,4,1,2,3,1,2]

从下标 0 出发,跳数 0;扫描当前层能覆盖的所有位置,找出下一层最远能到哪。

nums · 蓝色是当前跳跃层能覆盖的范围
0
1
2
3
4
5
6
2
4
1
2
3
1
2
end 是当前跳数能到达的最远位置;farthest 是扫描过程中发现的下一层边界。
状态
jumps=0end=0farthest=0
1 / 5
查看 C++ 代码

延伸阅读

  • 最少跳跃、最少步数这类“每步覆盖一个区间”的问题,通常都能转成 BFS 分层,再用 end/farthest 压成 O(1) 空间。
  • 第 55 题只问能否到达,维护一个 maxReach 即可;本题问最少步数,需要额外记录层边界。