【LeetCode】45. 跳跃游戏 II
解题思路
该问题需要找到从数组起点到终点的最小跳跃次数,贪心算法是最优解决方案。核心策略是:
- 局部最优:每次跳跃选择当前能覆盖的最远范围,减少后续跳跃次数。
- 全局最优:通过动态维护跳跃边界,确保总跳跃次数最少。
关键步骤
-
变量定义:
jumps:记录跳跃次数(初始为0)。currentEnd:当前跳跃能到达的最远位置(初始为0)。maxFar:全局能到达的最远位置(动态更新)。
-
遍历与更新:
- 遍历数组,每一步更新
maxFar = max(maxFar, i + nums[i])。 - 当索引
i到达currentEnd时触发跳跃,更新currentEnd为最新maxFar,并增加跳跃次数。 - 若
currentEnd已覆盖终点(>= n-1),提前终止循环。
- 遍历数组,每一步更新
-
边界处理:
- 数组长度为1时直接返回0(无需跳跃)。
func jump(nums []int) int { n := len(nums) if n == 1 { return 0 } jumps, currentEnd, maxFar := 0, 0, 0 for i := 0; i < n; i++ { if i + nums[i] > maxFar { maxFar = i + nums[i] } if i == currentEnd { jumps++ currentEnd = maxFar if currentEnd >= n-1 { break } } } return jumps }
复杂度分析
| 指标 | 值 | 说明 |
|---|---|---|
| 时间复杂度 | O(n) | 仅需一次线性遍历数组 |
| 空间复杂度 | O(1) | 仅使用常数级变量 |
测试用例验证
-
示例1:
nums := []int{2, 3, 1, 1, 4} fmt.Println(jump(nums)) // 输出: 2
- 步骤解析:
- 初始
currentEnd=0,maxFar=0。 i=0: 更新maxFar=2,触发跳跃,jumps=1,currentEnd=2。i=1: 更新maxFar=4。i=2: 到达currentEnd=2,触发跳跃,jumps=2,currentEnd=4(覆盖终点)。
- 初始
- 步骤解析:
-
示例2:
nums := []int{2, 3, 0, 1, 4} fmt.Println(jump(nums)) // 输出: 2
- 步骤解析:
- 初始
currentEnd=0,maxFar=0。 i=0: 更新maxFar=2,触发跳跃,jumps=1,currentEnd=2。i=1: 更新maxFar=4。i=2: 到达currentEnd=2,触发跳跃,jumps=2,currentEnd=4。
- 初始
- 步骤解析:
-
边界用例:
- 单元素数组:
nums := []int{5} fmt.Println(jump(nums)) // 输出: 0
- 需多次跳跃:
nums := []int{1, 1, 1, 1, 1} fmt.Println(jump(nums)) // 输出: 4
- 单元素数组:
核心逻辑总结
- 贪心策略优势:相比动态规划(时间复杂度 O(n²)),贪心算法通过单次遍历实现高效求解。
- 跳跃触发条件:到达当前边界时强制跳跃,确保每一步覆盖范围最大化。
- 提前终止优化:避免无效遍历,提升性能。
通过结合贪心策略与边界动态更新,该方案在保证正确性的同时达到最优时间复杂度,适用于大规模输入场景。

浙公网安备 33010602011771号