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

【LeetCode 热题 100】45. 跳跃游戏 II

Problem: 45. 跳跃游戏 II
给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。
每个元素 nums[i] 表示从索引 i 向后跳转的最大长度。换句话说,如果你在索引 i 处,你可以跳转到任意 (i + j) 处:
0 <= j <= nums[i] 且
i + j < n
返回到达 n - 1 的最小跳跃次数。测试用例保证可以到达 n - 1。

文章目录

  • 整体思路
  • 完整代码
  • 时空复杂度
    • 时间复杂度:O(N)
    • 空间复杂度:O(1)

整体思路

这段代码旨在解决经典的 “跳跃游戏 II” (Jump Game II) 问题。与判断“能否到达”的第一代问题不同,此问题要求在假设总能到达终点的前提下,计算出到达数组最后一个位置所需的 最小跳跃次数

该算法采用了一种非常高效的 贪心算法,其思想可以类比为 广度优先搜索 (BFS)。它不是关注每一步具体跳到哪里,而是在每一“跳”的范围内,寻找下一“跳”能到达的最远距离。

算法的逻辑步骤如下:

  1. 定义边界

    • 算法使用两个核心变量来定义跳跃的边界:
      • curRight当前这一跳所能到达的最远边界。可以理解为 BFS 中当前层的右边界。
      • nxtRight:从当前层(0curRight 之间的所有位置)出发,下一跳所能到达的最远边界。
    • ans 变量用于累计跳跃的次数。
  2. 贪心遍历

    • 算法通过一个 for 循环遍历数组。循环的终止条件是 i < nums.length - 1,这一点非常关键,因为我们只需要考虑从倒数第二个位置(或之前)起跳的情况,一旦到达或越过最后一个位置,就不需要再跳了。
    • 在当前跳跃范围内寻找最优的下一步:在循环的每一步(i0curRight),我们都在当前可达的范围内。对于每个位置 i,我们计算从它出发能跳到的最远距离 nums[i] + i。然后,我们用这个值去贪心地更新 nxtRight (nxtRight = Math.max(nxtRight, nums[i] + i))。这确保了 nxtRight 始终记录着从当前这一跳的覆盖范围内,能为下一跳创造的最远落点。
    • 执行跳跃:当循环变量 i 到达了 curRight 的边界时,意味着我们已经遍历完了当前这一跳能到达的所有位置。此时,我们必须执行一次跳跃才能继续前进。
      • if (i == curRight) 这个条件就是“执行跳跃”的触发器。
      • 当触发时,我们将 curRight 更新为 nxtRight,这相当于进入了 BFS 的下一层,设定了新的、更远的可达边界。
      • 同时,我们将跳跃次数 ans 加一。
  3. 返回结果

    • 当循环结束时,ans 中就记录了到达终点所需的最小跳跃次数。

完整代码

class Solution {/*** 计算到达数组最后一个位置所需的最小跳跃次数。* @param nums 数组,每个元素代表在该位置的最大跳跃长度。* @return 最小跳跃次数*/public int jump(int[] nums) {// curRight: 当前这一跳能够到达的最远右边界。int curRight = 0;// nxtRight: 在当前跳跃的覆盖范围内,下一步能够到达的最远右边界。int nxtRight = 0;// ans: 记录跳跃的次数,即结果。int ans = 0;// 遍历数组。循环到倒数第二个元素即可,因为我们的目标是“到达”最后一个位置,// 而不是从最后一个位置起跳。for (int i = 0; i < nums.length - 1; i++) {// 贪心选择:更新下一步能到达的最远距离。// 在当前跳跃的可达范围内(i 从 0 到 curRight),// 我们不断计算从每个位置 i 出发能跳到的最远点 (nums[i] + i),// 并用它来更新 nxtRight。nxtRight = Math.max(nxtRight, nums[i] + i);// 触发跳跃的条件:当 i 到达了当前跳跃的边界。// 这意味着我们已经考察完了当前这一跳能到达的所有位置,// 必须进行一次新的跳跃才能继续前进。if (i == curRight) {// 更新当前跳跃的边界为下一步能到达的最远边界。curRight = nxtRight;// 跳跃次数加一。ans++;}}// 循环结束后,ans 即为最小跳跃次数。return ans;}
}

时空复杂度

时间复杂度:O(N)

  1. 循环:算法的核心是一个 for 循环,它从 i = 0 遍历到 nums.length - 2。这个循环最多执行 N-1 次,其中 Nnums 数组的长度。
  2. 循环内部操作
    • 在循环的每一次迭代中,执行的都是基本的 Math.max、加法、比较和赋值操作。
    • 这些操作的时间复杂度都是 O(1)

综合分析
算法由 N-1 次 O(1) 的操作组成。因此,总的时间复杂度是 (N-1) * O(1) = O(N)

空间复杂度:O(1)

  1. 主要存储开销:算法只使用了几个固定数量的整型变量(curRight, nxtRight, ans, i)。
  2. 空间大小:这些变量的数量不随输入数组 nums 的大小 N 而改变。

综合分析
算法没有使用任何与输入规模 N 成比例的额外数据结构(如新数组或哈希表)。因此,其额外辅助空间复杂度为 O(1)

参考灵神

http://www.dtcms.com/a/332504.html

相关文章:

  • 【swift】SwiftUI动画卡顿全解:GeometryReader滥用检测与Canvas绘制替代方案
  • 如何使用亚马逊云科技EC2服务部署语音转写系统
  • 自动驾驶系统“测试”的“要求”与“规范体系”
  • L4 级别自动驾驶 软件架构设计
  • Flask错误处理与会话技术详解
  • 什么是可信空间的全域节点、区域节点、业务节点?
  • python学习 调用硅基流动 对话模型接口 实现 流式输出
  • 剧本杀小程序系统开发:重构推理娱乐生态
  • Spring WebFlux 性能优化实践指南
  • DAY 46 通道注意力(SE注意力)
  • 穿越数学时空:微积分的前世今生与无限未来
  • [论文阅读] 人工智能 | 当Hugging Face遇上GitHub:预训练语言模型的跨平台同步难题与解决方案
  • python30-正则表达式
  • 【模型评估中的BLEU、ROUGE、Bertscore、BERT分别什么意思?】
  • 把 AI 装进“冰箱贴”——基于超低功耗语音合成的小屏电子价签
  • 双面盲文刻印机市场报告:需求增长与技术升级驱动行业发展​
  • 计组-单周期cpu与多周期cpu对比
  • 杭州网站建设,外贸独立站搭建攻略分享
  • System V通信机制
  • 博弈论06——PPAD复杂度问题
  • 47.分布式事务理论
  • demo 通讯录 + 城市选择器 (字母索引左右联动 ListItemGroup+AlphabetIndexer)笔记
  • 2025最新:如何禁止指定软件联网?
  • 字符LCD显示模块是什么?
  • sqli-labs通关笔记-第50关 GET数值型order by堆叠注入(手工注入+脚本注入两种方法)
  • 智能工厂生产监控大屏-vue纯前端静态页面练习
  • [git] 当GitHub宕机时,我们如何协作?| github同步gitee的部署方法
  • 通俗易懂理解盲超分
  • 「iOS」————APP启动优化
  • 中年海尔,是时候押注新方向了