LeetCode 第 55 题:跳跃游戏(Jump Game)
字数 1235 2025-10-25 23:05:15
好的,我们接下来讲解 LeetCode 第 55 题:跳跃游戏(Jump Game)。
题目描述
给定一个非负整数数组 nums,你最初位于数组的 第一个下标。数组中的每个元素代表你在该位置可以跳跃的 最大长度。
你的目标是判断你是否能够到达最后一个下标。
示例 1:
输入:nums = [2,3,1,1,4]
输出:true
解释:可以先跳 1 步到下标 1,然后再跳 3 步到达最后一个下标。
示例 2:
输入:nums = [3,2,1,0,4]
输出:false
解释:无论怎样,总会到达下标 3 的位置,但该位置的最大跳跃长度是 0,所以永远无法到达最后一个下标。
解题思路:贪心算法(Greedy)
这个问题最直观的解法是使用 贪心策略。我们不需要精确地计算每一步跳到哪里,而是关注 当前能到达的最远位置。
核心思想
- 维护一个变量
max_reach,表示 从起点出发,当前能到达的最远下标。 - 遍历数组中的每一个位置
i:- 如果
i已经超过了max_reach,说明这个位置根本到不了,更别说跳到终点了,直接返回false。 - 否则,更新
max_reach为max(max_reach, i + nums[i])。 - 如果
max_reach已经大于等于最后一个下标,说明可以到达终点,提前返回true。
- 如果
为什么这样可行?
因为对于每一个能到达的位置 i,它都可以帮助我们将跳跃范围扩展到 i + nums[i]。我们只需要一直维护这个最远距离,并确保在遍历过程中不会出现“断档”(即当前位置 i 比最远距离还远)即可。
逐步推理示例
示例 1:nums = [2, 3, 1, 1, 4]
- 初始状态:
max_reach = 0(起点下标 0)。 - 遍历:
i = 0:0 <= 0(能到达),更新max_reach = max(0, 0 + 2) = 2。i = 1:1 <= 2(能到达),更新max_reach = max(2, 1 + 3) = 4。此时4 >= 4(终点),返回true。
示例 2:nums = [3, 2, 1, 0, 4]
- 初始状态:
max_reach = 0。 - 遍历:
i = 0:0 <= 0,更新max_reach = max(0, 0 + 3) = 3。i = 1:1 <= 3,更新max_reach = max(3, 1 + 2) = 3。i = 2:2 <= 3,更新max_reach = max(3, 2 + 1) = 3。i = 3:3 <= 3,更新max_reach = max(3, 3 + 0) = 3。i = 4:4 > 3(当前位置已经超过能到达的最远距离),返回false。
代码实现(Python)
def canJump(nums):
n = len(nums)
max_reach = 0 # 当前能到达的最远下标
for i in range(n):
# 如果当前位置已经超过能到达的最远距离,则无法继续
if i > max_reach:
return False
# 更新能到达的最远距离
max_reach = max(max_reach, i + nums[i])
# 如果已经能到达终点,提前结束
if max_reach >= n - 1:
return True
return True # 如果遍历完成,说明能到达终点
复杂度分析
- 时间复杂度:O(n),只需遍历一次数组。
- 空间复杂度:O(1),只使用了常数级别的额外空间。
总结
这道题是一个典型的 贪心算法 应用,关键在于理解:我们只需维护当前能到达的最远位置,而不需要模拟每一步的跳跃。这种方法既高效又直观,能够快速判断是否可达终点。