问题背景
本文背景是leetcode的一道经典题目:跳跃游戏,描述如下:
给定一个非负整数数组 nums
,初始位于数组的第一个位置(下标0)。数组中的每个元素表示在该位置可以跳跃的最大长度。判断是否能够到达最后一个下标。
示例:
- 输入:[2,3,1,1,4] → 输出:true
- 输入:[3,2,1,0,4] → 输出:false
解题思路
贪心算法解法
核心思想:维护一个当前能够到达的最远位置,遍历数组时不断更新这个值。
算法步骤分解
- 初始化
max_reach = 0
(当前能到达的最远位置) - 遍历数组:
- 如果当前位置
i > max_reach
,说明无法到达,返回false
- 更新
max_reach = max(max_reach, i + nums[i])
- 如果
max_reach ≥ 最后一个下标
,提前返回true
- 如果当前位置
- 遍历结束返回
true
代码实现
class Solution {
public boolean canJump(int[] nums) {
int maxReach = 0;
for (int i = 0; i < nums.length; i++) {
if (i > maxReach) return false;
maxReach = Math.max(maxReach, i + nums[i]);
if (maxReach >= nums.length - 1) return true;
}
return true;
}
}
算法原理解析
- 初始化:
maxReach
记录当前能到达的最远位置 - 遍历过程:
- 检查当前位置是否可达(
i > maxReach
) - 更新最远可达位置(
i + nums[i]
) - 提前终止条件(已到达终点)
- 检查当前位置是否可达(
- 返回值:遍历完成仍未返回,说明可以到达终点
示例分析
示例1:[2,3,1,1,4]
i=0: maxReach = max(0, 0+2)=2
i=1: 1<=2 → maxReach = max(2, 1+3)=4 (覆盖终点)
直接返回true
示例2:[3,2,1,0,4]
i=3: maxReach=3
i=4: 4>3 → 返回false
常见误区
- 错误解法:简单检查是否有0存在
- 反例:[2,0,2,0,1]可以到达终点。
- 过度优化:不需要记录具体路径
实际应用
- 网络路由选择
- 游戏关卡设计
- 资源调度问题