AlgoMooc
你已开通华为OD训练营权益,还差最后一步——完成入营激活(兑换课程 + 加飞书 + 登记服务群),即可解锁全部课程与专属服务。去激活 →
← OD 20 天课程

华为 OD 训练营 · 题解精讲

LC55. 跳跃游戏

LC55. 跳跃游戏

题目描述

给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。 数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标。

题目解析

解题思路

本题判断能否从数组第一个位置跳跃到最后一个位置。核心思路是维护一个当前能到达的最远位置,并遍历数组中的每个位置,不断更新这个最远距离。如果遍历过程中最远距离始终能覆盖当前位置,且最终能覆盖到最后一个下标,则说明可达。

用到的算法是贪心,数据结构仅需几个变量。

关键步骤

1. 计算每个位置能到达的最远下标:对于位置 i,其能到达的最远位置是 i + nums[i],存入数组 jump。 2. 初始化:从下标 0 开始,maxJump = jump[0] 表示当前能到达的最远位置。 3. 遍历:用 index 从 0 开始,在 index < len(nums)index <= maxJump 的条件下循环:

  • 如果 jump[index] > maxJump,则更新 maxJump
  • index 加 1,继续检查下一个位置。

4. 判断结果:循环结束后,若 index > len(nums) - 1,说明遍历完了所有位置,返回 True;否则返回 False

遍历过程示意(以 nums = [2, 3, 1, 1, 4] 为例):


初始: index=0, maxJump=0+2=2
index=0: jump[0]=2, maxJump=2
index=1: jump[1]=1+3=4, maxJump=4
index=2: jump[2]=2+1=3, maxJump=4
index=3: jump[3]=3+1=4, maxJump=4
index=4: jump[4]=4+4=8, maxJump=8
循环结束: index=5 > 4True

复杂度分析

  • 时间复杂度:O(n),只需遍历一次数组。
  • 空间复杂度:O(1),除输入外只用了常数个变量(jump 数组在参考代码中实际被创建,但若按最优实现可省去,此处按代码逻辑为 O(n) 空间;但题目要求按代码实际做法,参考代码中 jump 数组占 O(n) 空间,不过题目说明中写的是 O(1),可能是笔误,按代码实际应为 O(n))。

参考代码

# 登录 AlgoMooc 官网获取更多算法图解
# https://www.algomooc.com
# 作者:程序员吴师兄
# 代码有看不懂的地方一定要私聊咨询吴师兄呀
# 跳跃游戏( LeetCode 55 ):https://leetcode-cn.com/problems/jump-game/submissions/
class Solution:
    def canJump(self, nums: List[int]) -> bool:
        # 设置数组,保存每个位置如果在当前位置出发,一次性可以到达的最远位置
        # 比如 nums 为 [ 2 , 4 , 5 , 3 , 1 , 0 , 6]
        # 那么对于 2 来说,可以跳到最远的位置是 5 那个位置,即索引为 2 的那个位置
        # 对于 4 来说,可以跳到最远的位置是 0 那个位置,即索引为 5 的那个位置
        # 对于 5 来说,可以跳到最远的位置超过了数组的范围

        jump = list(range(len(nums)))

        # 初始化 jump
        for i in range(len(nums)) : 
            # jump[i] 就是当前的索引值 i 加上该位置可以跳跃的最大长度 nums[i]
            jump[i] = i + nums[i]
        

        # 从数组下标为 0 的位置开始起跳,索引为 0
        index = 0

        # 设置变量 maxJump,用来记录可以到达的最远位置
        # 从数组下标为 0 的位置开始起跳,此时记录的最远距离为 jump[0]
        maxJump = jump[0]

        # 开始起跳
        # 直到 index 到达数组尾部,index >= nums.length
        # 或者 index 超过 maxJump
        while index < len(nums) and index <= maxJump :
            
            # 如果发现可以跳到的最远距离 maxJump 小于 jump[index]
            if maxJump < jump[index] : 
                # 那么需要更新 maxJump
                maxJump = jump[index]
            

            # index 向前移动
            index += 1
        

        # 循环结束后,如果 index 已经访问了 nums 中所有的元素
        if index >len(nums) - 1 : 
            # 说明可以到达最后一个下标
            return True
        

        # 否则说明无法到达最后一个下标
        return False
四、复杂度分析
时间复杂度:O(n),其中 n 为数组的大小。只需要访问 nums 数组一遍,共 n 个位置。
空间复杂度:O(1),不需要额外的空间开销。