当前位置: 首页 > news >正文

LeetCode 55.跳跃游戏:贪心策略下的可达性判断

一、问题定义与核心挑战

1.1 问题描述

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

1.2 核心特征与难点

  • 跳跃规则:从位置 i 出发,可跳到 i+1i+2、…、i+nums[i] 中的任意位置(不超过数组边界)
  • 可达性判断:无需记录具体路径,只需判断终点是否可达
  • 高效性要求:暴力枚举所有路径会超时,需找到贪心或动态规划的优化解法

示例

  • 输入:nums = [2,3,1,1,4] → 输出:true(路径:0→1→4
  • 输入:nums = [3,2,1,0,4] → 输出:false(最远只能到索引3,无法到达4)

二、解题思路:贪心算法的最大覆盖范围

2.1 核心思想

贪心算法的关键在于跟踪当前可到达的最大范围(覆盖范围),并通过不断扩展覆盖范围来判断终点是否可达:

  • 局部最优:在当前覆盖范围内,找到能跳得最远的位置(即 i + nums[i] 最大)
  • 全局最优:持续扩展覆盖范围,若覆盖范围包含终点,则返回 true;若遍历完当前覆盖范围仍未到达终点,则返回 false

2.2 直观理解

可以将数组想象成一段需要跨越的区域,每个位置 i 能提供一个“辐射范围” [i, i+nums[i]]

  • 初始时,辐射范围从 0 开始(cover = 0
  • 遍历辐射范围内的每个位置,计算其能到达的最远距离,更新辐射范围
  • 若辐射范围扩展到包含终点(nums.length - 1),则成功;若辐射范围无法再扩展且未包含终点,则失败

三、代码逐行解析

3.1 边界条件处理

if (nums.length <= 1) {return true;
}
  • 若数组长度为0或1(起点即终点),必然可达,直接返回 true

3.2 核心变量与遍历逻辑

int cover = 0;  // 当前可到达的最大索引(覆盖范围)// 遍历当前覆盖范围内的所有位置
for (int i = 0; i <= cover; i++) {// 扩展覆盖范围:取当前位置能到达的最远距离与现有覆盖范围的最大值cover = Math.max(i + nums[i], cover);// 若覆盖范围已包含终点,直接返回trueif (cover >= nums.length - 1) {return true;}
}

3.3 最终判断

return false;  // 遍历完所有可达位置仍未到达终点,返回false

四、算法执行过程演示

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

  • 初始:cover = 0,遍历 i=0(在覆盖范围内)
    • i + nums[i] = 0 + 2 = 2cover 更新为 2
    • 覆盖范围 [0,2] 未包含终点(4),继续遍历
  • i=1(在覆盖范围内)
    • i + nums[i] = 1 + 3 = 4cover 更新为 4
    • 覆盖范围 [0,4] 包含终点(4)→ 返回 true

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

  • 初始:cover = 0,遍历 i=0
    • i + nums[i] = 0 + 3 = 3cover 更新为 3
    • 覆盖范围 [0,3] 未包含终点(4),继续遍历
  • i=1(在覆盖范围内)
    • i + nums[i] = 1 + 2 = 3cover 保持3
  • i=2(在覆盖范围内)
    • i + nums[i] = 2 + 1 = 3cover 保持3
  • i=3(在覆盖范围内)
    • i + nums[i] = 3 + 0 = 3cover 保持3
  • 遍历结束(i=4 超出覆盖范围 3),未到达终点 → 返回 false

五、核心逻辑深度解析

5.1 为什么遍历范围是 i <= cover

cover 表示当前能到达的最远索引,只有在这个范围内的位置 i 是可达的,其跳跃才能被纳入考虑。超出 cover 的位置尚未可达,无需遍历。

5.2 为什么 cover = Math.max(i + nums[i], cover) 能保证最优?

  • i + nums[i] 是位置 i 能到达的最远距离
  • 取最大值确保覆盖范围始终是当前可达的最大范围,体现了“贪心”思想(每次都选择能跳得最远的选项)

5.3 为什么无需回溯?

贪心算法的特点是“只看当前最优,不回头”。本题中,一旦覆盖范围确定,所有在范围内的位置都已被考虑,无需回溯到之前的位置重新判断,因为扩展后的覆盖范围已包含了所有可能的更优选择。

六、算法复杂度分析

  • 时间复杂度O(n),其中 n 是数组长度。最坏情况下,需遍历到覆盖范围的边界(最多为 n-1),但每个元素仅被访问一次。
  • 空间复杂度O(1),仅使用常数个变量(coveri),与输入规模无关。

七、常见误区与优化说明

7.1 误区1:尝试记录具体路径

题目只需判断可达性,无需记录路径。试图记录路径会增加空间复杂度(如使用数组或列表存储路径),且无必要。

7.2 误区2:遍历所有元素而非覆盖范围

若错误地遍历整个数组(i < nums.length),而非限制在 i <= cover,会导致访问不可达的位置,虽然结果可能正确,但会降低效率(尤其当覆盖范围远小于数组长度时)。

7.3 优化点:提前终止判断

在每次更新 cover 后立即判断是否包含终点,可在早期终止循环(如示例1中,i=1 时已覆盖终点,无需继续遍历 i=2)。

八、总结:贪心算法在跳跃问题中的应用

本题的贪心解法通过跟踪最大覆盖范围,高效判断终点可达性,核心在于:

  1. 范围更新:在当前可达范围内,不断扩展最大覆盖范围
  2. 早期终止:一旦覆盖范围包含终点,立即返回结果
  3. 效率优势:线性时间复杂度,常数空间复杂度,远超暴力枚举的性能

这种“覆盖范围扩展”的思路可推广到其他可达性问题(如 Jump Game II 求最少跳跃次数),是贪心算法解决范围优化类问题的典型范例。

http://www.lryc.cn/news/623040.html

相关文章:

  • Windows 操作系统 - Windows 恢复浏览器标题栏颜色
  • tensorrt-llm0.20.0:Prometheus3.5.0通过间接采集,进行性能指标分析
  • AirReceiverLite:轻松实现手机隔空投屏
  • 自动驾驶中的传感器技术24.1——Camera(16)
  • 电路方案分析(二十二)适用于音频应用的25-50W反激电源方案
  • 40 C++ STL模板库9-容器2-vector
  • 下载数据集文件夹权限错误问题解决方案
  • PHP域名授权系统网站源码/授权管理工单系统/精美UI/附教程
  • 西门子SMART PLC监控时间戳问题BUG修复
  • weapp:按钮去除背景
  • 云计算-Kubernetes+Istio 实现金丝雀发布:流量管理、熔断、流量镜像、ingreess、污点及pv案例实战
  • leetcode_42 接雨水
  • H20芯片与中国的科技自立:一场隐形的博弈
  • 内网穿透实战笔记 1panel 面板部署 frps,Windows 部署 frpc
  • Win11和Win10共享打印机提示709用添加Windows凭据来解决的小方法
  • 自适应阈值二值化参数详解 ,计算机视觉,图片处理 邻域大小 调整常数(C=3)和可视化调节参数的应用程序
  • vscode中用python调用matlab的函数(环境安装)
  • 计算机网络:(十五)TCP拥塞控制与拥塞控制算法深度剖析
  • 安全审计-firewall防火墙
  • 在STM32F103上进行FreeRTOS移植和配置(STM32CubeIDE)
  • MySQL的《Buffer-pool》和《连接池》介绍
  • LangChain4j:基于 SSE 与 Flux 的 AI 流式对话实现方案
  • lesson40:PyMySQL完全指南:从基础到高级的Python MySQL交互
  • 数据结构:层序遍历 (Level-order Traversal)
  • 图论Day4学习心得
  • Kafka 面试题及详细答案100道(11-22)-- 核心机制1
  • 代码随想录Day52:图论(孤岛的总面积、沉没孤岛、水流问题、建造最大岛屿)
  • Cmake学习笔记
  • 代码随想录算法训练营四十三天|图论part01
  • 数字化与人工智能的崛起及其社会影响研究报告