LeetCode 跳跃类问题的解题技巧:跳跃游戏与最少跳跃数

ops/2025/2/1 15:19:58/

LeetCode 跳跃类问题的解题技巧:跳跃游戏与最少跳跃数

在 LeetCode 中,有一类经典的题目是关于跳跃的,例如 跳跃游戏跳跃游戏 II。这些问题通常要求我们判断是否能从数组的起始位置跳跃到结束位置,或者求得最少跳跃次数。解决这类问题时,贪心算法是一个非常有效的策略。

本文将通过 跳跃游戏(Can Jump)跳跃游戏 II(Jump) 两道题目,讲解如何运用贪心算法高效地解决这类问题。


1. 跳跃游戏 (Can Jump)

题目概述:

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

解题思路:

贪心策略:
  • 目标:检查是否能够跳跃到最后一个位置。我们从数组的第一个元素开始,尝试不断跳跃,并跟踪当前能到达的最远位置。
  • 核心思想:我们维护一个变量 cur,表示当前能够到达的最远位置。遍历数组时,若当前位置能够跳跃的最远位置 i + nums[i] 大于 cur,则更新 cur,如果在过程中发现当前位置无法继续跳跃(即 cur 不再更新),则返回 False
关键步骤:
  1. 从第一个位置开始,初始化 cur = 0(表示当前能跳跃到的位置)。
  2. 遍历每一个位置 i,如果 i 大于 cur,则说明当前位置无法到达,返回 False
  3. 如果 i + nums[i] 大于当前的 cur,则更新 cur
  4. 如果遍历结束后,cur 能到达最后一个位置,则返回 True
代码实现:
class Solution:def canJump(self, nums: List[int]) -> bool:cur = 0  # 当前能到达的最远位置n = len(nums)for i in range(n):if i > cur:  # 如果当前位置不能到达,返回 Falsereturn Falsecur = max(cur, i + nums[i])  # 更新当前能到达的最远位置return True  # 如果遍历结束,说明能到达最后一个位置
示例:
  • 输入:nums = [2, 3, 1, 1, 4]

  • 输出:True

    解释:可以先从下标 0 跳到下标 1,再从下标 1 跳到下标 4。


2. 跳跃游戏 II (Jump)

题目概述:

nums 数组中,每个元素代表你在该位置的最大跳跃长度。你需要返回从数组的起始位置到达最后一个位置所需的最少跳跃次数。

解题思路:

贪心策略:
  • 目标:我们需要通过最少的跳跃次数到达数组的最后一个元素。
  • 核心思想:每次跳跃时,我们选择跳得最远的点,确保每次跳跃都能覆盖尽可能多的位置。为了实现这一点,我们维护两个变量:curne
    • cur:表示当前跳跃到达的最远位置。
    • ne:表示在当前跳跃中能到达的最远位置。
关键步骤:
  1. 初始化 cur = 0ne = 0res = 0,表示跳跃次数。
  2. 遍历数组,更新 ne 为当前能跳到的最远位置。
  3. 每当遍历到 cur 时,说明需要一次新的跳跃(即增加 res),并更新 curne
  4. 如果遍历到最后一个位置,则返回跳跃次数。
代码实现:
class Solution:def jump(self, nums: List[int]) -> int:n = len(nums)cur = 0  # 当前跳跃的最远位置ne = 0  # 当前跳跃能够达到的最远位置res = 0  # 跳跃次数for i in range(n - 1):  # 不需要跳跃到最后一个位置ne = max(ne, i + nums[i])  # 更新最远跳跃位置if i == cur:  # 如果当前位置已经到达了当前跳跃的最远位置res += 1  # 跳跃次数加 1cur = ne  # 更新当前跳跃的最远位置if cur >= n - 1:  # 如果已经能到达最后一个位置,结束breakreturn res
示例:
  • 输入:nums = [2, 3, 1, 1, 4]

  • 输出:2

    解释:可以先从下标 0 跳到下标 1,再从下标 1 跳到下标 4。


做题技巧总结

贪心算法在跳跃问题中的应用

  1. 判断能否到达最后一个位置(跳跃游戏 I)

    • 使用 cur 记录当前最远可达位置,遍历时若当前位置 i 超过 cur,说明无法到达该位置,直接返回 False
    • 每次尽量更新最远可达的位置 cur,确保每一步都能够最大化覆盖区间。
  2. 计算最少跳跃次数(跳跃游戏 II)

    • curne 的配合帮助我们在每次遍历时选出最远的跳跃目标。
    • 每当 i == cur 时,说明必须进行一次跳跃,更新 curne
    • 跳跃的次数 res 每次增加,直到能到达最后一个位置。

贪心算法的优点

  • 时间效率高:这类问题的时间复杂度为 O(n),适合处理大规模数据。
  • 简单直观:通过维护两个变量 curne,不断选择当前能跳得最远的点,快速得到最优解。

注意事项

  • 跳跃过程中要注意“死胡同”:在一些特殊情况下,可能会遇到无法跳跃的情形。例如,在跳跃游戏 II 中,如果遇到 nums[i] == 0 且无法到达后续位置,就需要提前终止。
  • 处理边界条件:确保在输入的边界条件下(如数组长度为 1 或所有元素都为 0)能正确处理。

总结

通过贪心算法,我们能够高效解决跳跃游戏类问题,确保以最少的跳跃次数覆盖目标区间或判断是否能到达终点。掌握这种策略,你就能在面对这类问题时游刃有余,快速找到最优解。


http://www.ppmy.cn/ops/154781.html

相关文章

C++ list

list需知: list不会出现insert迭代器失效问题 链表插入不会影响原有数据相对位置,且不用扩容 但是erase会导致相对数据位置移动,所有其erase会导致迭代器失效 list排序效率很低 不建议使用 小规模数据量可以使用,比较方便 此外…

Github 2025-01-31Java开源项目日报 Top10

根据Github Trendings的统计,今日(2025-01-31统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Java项目10C项目1Kotlin项目1Bazel:快速、可扩展的多语言构建系统 创建周期:3564 天开发语言:Java协议类型:Apache License 2.0Star数量:2…

字符串,集合

String 概述 java.lang.String 类代表字符串,Java 程序中的所有字符串文字(例如“abc”)都为此类的对象 注意:字符串的内容是不会发生改变的,它的对象在创建后不能被更改 String是Java定义好的一个类。定义在java.lang 包中,所…

DDD - 领域驱动设计分层架构:构建可演化的微服务架构

文章目录 引言1. 什么是DDD分层架构?1.1 DDD分层架构的演变1.2 四层架构的起源与问题1.3 依赖倒置和五层架构 2. DDD分层架构的核心层次2.1 用户接口层(User Interface Layer)2.2 应用层(Application Layer)2.3 领域层…

kafka消费者详细介绍(超级详细)

文章目录 一、Kafka 消费者与消费者组1.1 Kafka 消费者(Consumer)概述1.1.1 消费者工作流程1.1.2 消费者的关键配置 1.2 Kafka 消费者组(Consumer Group)概述1.2.1 消费者组的工作原理1.2.2 消费者组的优点1.2.3 消费者组的再均衡…

Linux网络编程中的零拷贝:提升性能的秘密武器

在当今数字化时代,网络应用的性能至关重要。而在网络编程中,数据传输的效率直接影响着应用的整体性能。传统的数据传输方式往往涉及大量的数据拷贝和上下文切换,这在高并发、大数据量的场景下,会成为性能瓶颈。零拷贝技术的出现&a…

25.Word:学生成绩管理系统【8】

目录 NO1.2​ NO3 NO4.5.6 NO7.8.9​​ NO1.2 F12另存为→考生文件夹布局→页面设置对话框→纸张大小→页边距:上下左右→文档网格: NO3 布局→分隔符→分节符:下一页(封面、目录、一、二、三、四)6节双击页眉页…

Kotlin开发(六):Kotlin 数据类,密封类与枚举类

引言 想象一下,你是个 Kotlin 开发者,敲着代码忽然发现业务代码中需要一堆冗长的 POJO 类来传递数据。烦得很?别急,Kotlin 贴心的 数据类 能帮你自动生成 equals、hashCode,直接省时省力!再想想需要多种状…