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

【Leetcode hot 100】45.跳跃游戏Ⅱ

问题链接

45.跳跃游戏Ⅱ

问题描述

给定一个长度为 n0 索引整数数组 nums。初始位置在下标 0

每个元素 nums[i] 表示从索引 i 向后跳转的最大长度。换句话说,如果你在索引 i 处,你可以跳转到任意 (i + j) 处:

  • 0 <= j <= nums[i]
  • i + j < n
    返回到达 n - 1 的最小跳跃次数。测试用例保证可以到达 n - 1

示例 1:

输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。

示例 2:

输入: nums = [2,3,0,1,4]
输出: 2

提示:

  • 1 <= nums.length <= 10^4
  • 0 <= nums[i] <= 1000
  • 题目保证可以到达 n - 1

问题解答

贪心算法(最优解)

思路分析
贪心策略的核心逻辑:

  1. 定义关键变量
    • currentEnd:当前跳跃的“边界”(跳完当前这一步后,能到达的最远位置)。
    • farthest:在当前跳跃的覆盖范围内,所有位置能到达的最大距离(决定下一步的边界)。
    • jumps:记录跳跃次数。
  2. 遍历数组
    • 遍历过程中,不断更新farthest(即Math.max(farthest, i + nums[i])i + nums[i]表示从位置i能跳到的最远位置)。
    • 当遍历到currentEnd时,说明当前跳跃的覆盖范围已用尽,必须进行一次新的跳跃:
      • 跳跃次数jumps加1。
      • currentEnd更新为farthest(新的跳跃边界)。
      • 提前终止:若currentEnd已覆盖终点(currentEnd >= nums.length - 1),直接跳出循环(无需继续遍历)。

代码实现

class Solution {public int jump(int[] nums) {// 特殊情况:数组长度为1,无需跳跃if (nums.length == 1) {return 0;}int currentEnd = 0; // 当前跳跃的边界int farthest = 0;   // 当前覆盖范围内能到达的最远距离int jumps = 0;      // 跳跃次数// 遍历到倒数第二个位置即可(最后一个位置是终点,无需处理)for (int i = 0; i < nums.length - 1; i++) {// 更新当前覆盖范围内的最远距离farthest = Math.max(farthest, i + nums[i]);// 到达当前跳跃的边界,必须跳一次if (i == currentEnd) {jumps++;currentEnd = farthest; // 更新新的跳跃边界// 提前终止:新边界已覆盖终点if (currentEnd >= nums.length - 1) {break;}}}return jumps;}
}

复杂度分析

  • 时间复杂度O(n),仅遍历数组一次,每个元素处理一次。
  • 空间复杂度O(1),仅使用3个额外变量,无额外空间开销。

动态规划(辅助理解)

若对贪心策略不熟悉,可先通过动态规划理解“最少跳跃次数”的推导过程。动态规划的核心是“记录每个位置到终点的最少跳跃次数”,但效率低于贪心算法。

思路分析

  1. 定义DP数组dp[i]表示从位置i到达终点(nums.length - 1)的最少跳跃次数。
  2. 初始化
    • 终点位置dp[nums.length - 1] = 0(无需跳跃)。
    • 其他位置初始化为Integer.MAX_VALUE(表示初始状态下无法到达终点,后续更新)。
  3. 逆序推导
    • 从倒数第二个位置开始,逆序遍历每个位置i
    • 对每个位置i,遍历其能覆盖的所有位置jj的范围:i + 1Math.min(i + nums[i], nums.length - 1))。
    • dp[j]不为Integer.MAX_VALUE,则dp[i] = Math.min(dp[i], dp[j] + 1)(从i跳到j,再从j到终点,总次数+1)。

代码实现

class Solution {public int jump(int[] nums) {int n = nums.length;// dp[i]:从位置i到终点的最少跳跃次数int[] dp = new int[n];// 初始化:除终点外,其他位置初始化为“不可达”for (int i = 0; i < n - 1; i++) {dp[i] = Integer.MAX_VALUE;}dp[n - 1] = 0; // 终点无需跳跃// 逆序遍历:从倒数第二个位置开始推导for (int i = n - 2; i >= 0; i--) {// 遍历位置i能覆盖的所有位置jint maxJump = Math.min(i + nums[i], n - 1); // 避免越界for (int j = i + 1; j <= maxJump; j++) {// 若j可达终点,则更新dp[i]if (dp[j] != Integer.MAX_VALUE) {dp[i] = Math.min(dp[i], dp[j] + 1);}}}return dp[0]; // 从起点到终点的最少跳跃次数}
}

复杂度分析

  • 时间复杂度O(n²),最坏情况下每个位置需遍历其覆盖的所有位置(如数组全为n-1时)。
  • 空间复杂度O(n),需额外存储dp数组。

两种解法对比

解法时间复杂度空间复杂度适用场景
贪心算法O(n)O(1)追求高效,数组规模大(如10⁴
动态规划O(n²)O(n)理解“最少跳跃次数”的推导逻辑,小规模数组
http://www.dtcms.com/a/496747.html

相关文章:

  • 北京建设局网站百度seo快排软件
  • 免费优化网站建设中建一局
  • 流氓软件AlibabaProtect无需第三方软件无需重启电脑的清理方法
  • 自助建站网站手机网站设计规范
  • 平邑县建设局网站wordpress安装在哪
  • 东莞网站seo价格电脑系统重装wordpress
  • 做网站建设销售途径四川省住建设厅网站
  • 简单大气的企业网站广东网站建设建站模板
  • 2017自己做网站的趋势网络营销定价的特点有
  • BT BlueZ软硬件环境介绍
  • 智能防雷产品应用解决方案
  • 怎么样申请网站域名优秀的包装设计案例
  • 网站维护要求wordpress最好的编辑器下载地址
  • C++ 多态(1)
  • 中国空间站组成部分三门峡 网站开发
  • 监控运行大模型的显存占用率的方式
  • NumPy 快速入门
  • python-time和datetime
  • 东莞网站建设_东莞网页设计】最好看免费观看高清大全
  • vs 2017c 怎么建设网站WordPress图片加密
  • 力扣-删除重复的电子邮箱
  • Avalonia DataGrid 控件的LostFocus事件会多次触发
  • python做网站的优势wordpress 类似的
  • 58同城网站建设的不足网站建设顾问站建
  • CRMEB-PHP批量发货技术详解
  • 高扩展集群的实现方式:硬件与软件视角
  • 美妆企业网站模板企业购物网站开发
  • 行业网站解决方案营销网站制作公司
  • 常州网站推关键词排名规则
  • Prism框架下MVVM模式中命令实现