【LeetCode刷题】跳跃游戏

给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。

判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。

示例 1:

复制代码
输入:nums = [2,3,1,1,4]
输出:true
解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。

示例 2:

复制代码
输入:nums = [3,2,1,0,4]
输出:false
解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标。

提示:

  • 1 <= nums.length <=
  • 0 <= nums[i] <=

解题思路:

本题采用贪心算法,通过维护【当前能到达的最远下标】来判断是否能到达终点,时间复杂度为 O (n)(仅遍历数组一次),空间复杂度为 O (1)(仅用常数额外空间):

  1. 初始化max_reach为 0,表示初始时能到达的最远下标是 0;
  2. 遍历数组的每个下标i:
    • 若当前下标i超过了max_reach,说明无法到达该位置,直接返回false;
    • 更新max_reach为【当前max_reach】与【i + nums[i](当前位置能跳到的最远下标)】的较大值;
    • 若max_reach已覆盖最后一个下标(n-1),直接返回true(提前终止,提升效率);
  3. 遍历结束后(仅当数组长度为 1 时触发),返回true。

Python代码:

python 复制代码
from typing import List


class Solution:
    def canJump(self, nums: List[int]) -> bool:
        """
        判断是否能从数组第一个位置跳到最后一个位置
        :param nums: 整数数组,nums[i] 表示在第 i 个位置可以跳跃的最大长度
        :return: 能否到达最后一个位置,布尔值
        """
        # 边界情况1:数组为空,直接返回False(题目中nums通常非空,仅做鲁棒性处理)
        if not nums:
            return False
        # 边界情况2:数组只有1个元素,已经在最后位置,直接返回True
        if len(nums) == 1:
            return True

        max_reach = 0  # 记录当前能到达的最远下标
        n = len(nums)

        # 遍历数组(无需遍历到最后一个元素,因为只要能到达倒数第二个的最远覆盖最后一个即可)
        for i in range(n - 1):
            # 若当前下标超过了最远可达范围,说明无法到达该位置,更无法到终点
            if i > max_reach:
                return False
            # 更新最远可达范围:当前位置能跳到的最远位置 = 当前下标 + 最大跳跃长度
            max_reach = max(max_reach, i + nums[i])
            # 提前终止:若最远可达范围已覆盖最后一个下标,直接返回True
            if max_reach >= n - 1:
                return True

        # 遍历结束后仍未覆盖最后一个下标,返回False
        return False


# ------------------- 测试用例 -------------------
if __name__ == "__main__":
    solution = Solution()

    # 测试用例1:正常可到达
    nums1 = [2, 3, 1, 1, 4]
    print(f"测试用例1 [{nums1}]:{'true' if solution.canJump(nums1) else 'false'}")

    # 测试用例2:无法到达(卡在下标3)
    nums2 = [3, 2, 1, 0, 4]
    print(f"测试用例2 [{nums2}]:{'true' if solution.canJump(nums2) else 'false'}")

    # 测试用例3:边界情况(数组长度为1)
    nums3 = [0]
    print(f"测试用例3 [{nums3}]:{'true' if solution.canJump(nums3) else 'false'}")

    # 测试用例4:边界情况(第一个元素直接覆盖最后一个)
    nums4 = [5, 1, 0, 0, 0]
    print(f"测试用例4 [{nums4}]:{'true' if solution.canJump(nums4) else 'false'}")

    # 测试用例5:全0数组(长度>1)
    nums5 = [0, 0, 0]
    print(f"测试用例5 [{nums5}]:{'true' if solution.canJump(nums5) else 'false'}")

LeetCode提交代码:

python 复制代码
class Solution:
    from typing import List
    def canJump(self, nums: List[int]) -> bool:
        max_reach = 0  # 记录当前能到达的最远下标
        n = len(nums)
        
        for i in range(n):
            # 若当前下标超过了最远可达范围,说明无法到达
            if i > max_reach:
                return False
            # 更新最远可达范围(当前位置+最大跳跃长度)
            max_reach = max(max_reach, i + nums[i])
            # 若最远可达范围已覆盖最后一个下标,直接返回true
            if max_reach >= n - 1:
                return True
        
        # 遍历完成后(仅当数组长度为1时会走到这里)
        return True

程序运行截图展示:

总结

本文探讨了跳跃游戏问题的贪心算法解法。给定非负整数数组nums,初始位于第一个下标,每个元素表示可跳跃的最大长度。算法通过维护当前能到达的最远下标max_reach来判断是否能到达终点:遍历数组时若当前下标超过max_reach则返回false,否则更新max_reach为当前位置能跳到的最大距离。当max_reach覆盖终点时提前返回true。该方法时间复杂度O(n),空间复杂度O(1),高效解决了该问题。

相关推荐
inrichtt43 分钟前
第八课时:SPI总线揭秘:四线全双工通信的奥
c语言·数据结构·stm32·单片机·嵌入式硬件
信誓旦旦的程序猿1 小时前
【Python量化实战宝典 #08】可转债与债券接口手册:转股价·溢价率·纯债价值(Python 可跑)
java·python·股票数据api·股票数据api接口·股票api数据接口·股票量化数据api·股票量化数据接口
砚底藏山河1 小时前
python量化:行情数据回溯
java·开发语言·python·金融·maven
今年下半年1 小时前
AI智能体项目实战记录(02):初始化 Python 项目
开发语言·人工智能·python·fastapi
Williamtym1 小时前
PickGo Lab实践:用浏览器、Python和MCP串起机器人搬运仿真
开发语言·python·机器人
HPtiger1 小时前
数据结构——选择排序
数据结构·算法·排序算法
康实训1 小时前
老年评估仿真实训平台架构设计与老年人能力评估实训室教学落地实践
大数据·人工智能·算法·实训室·实训室建设
河南花仙子科技1 小时前
古镇非遗小游戏如何传播传统文化
游戏
DongQiShanRen2 小时前
六根硬件映射(四):归属澄清、两处不一致与卷十一总表
开发语言·人工智能·算法·rust·哈希算法·集成学习
CS创新实验室2 小时前
Python 对象“死“了之后去了哪?——引用计数与分代垃圾回收
开发语言·jvm·python