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_reachmax(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 = 00 <= 0(能到达),更新 max_reach = max(0, 0 + 2) = 2
    • i = 11 <= 2(能到达),更新 max_reach = max(2, 1 + 3) = 4。此时 4 >= 4(终点),返回 true

示例 2:nums = [3, 2, 1, 0, 4]

  • 初始状态:max_reach = 0
  • 遍历:
    • i = 00 <= 0,更新 max_reach = max(0, 0 + 3) = 3
    • i = 11 <= 3,更新 max_reach = max(3, 1 + 2) = 3
    • i = 22 <= 3,更新 max_reach = max(3, 2 + 1) = 3
    • i = 33 <= 3,更新 max_reach = max(3, 3 + 0) = 3
    • i = 44 > 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),只使用了常数级别的额外空间。

总结

这道题是一个典型的 贪心算法 应用,关键在于理解:我们只需维护当前能到达的最远位置,而不需要模拟每一步的跳跃。这种方法既高效又直观,能够快速判断是否可达终点。

好的,我们接下来讲解 LeetCode 第 55 题:跳跃游戏(Jump Game) 。 题目描述 给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的 最大长度 。 你的目标是判断你是否能够到达最后一个下标。 示例 1: 示例 2: 解题思路:贪心算法(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) 复杂度分析 时间复杂度 :O(n),只需遍历一次数组。 空间复杂度 :O(1),只使用了常数级别的额外空间。 总结 这道题是一个典型的 贪心算法 应用,关键在于理解:我们只需维护当前能到达的最远位置,而不需要模拟每一步的跳跃。这种方法既高效又直观,能够快速判断是否可达终点。