LeetCode Hot100(60/100)——55. 跳跃游戏

文章目录

一、题目背景与描述

题目链接:

https://leetcode.cn/problems/jump-game/

题目描述

给定一个非负整数数组 nums,你最初位于数组的第一个下标

数组中的每个元素代表你在该位置最多可以向前跳跃的步数

请判断你是否能够到达数组的最后一个下标


示例说明

示例 1:

text 复制代码
输入:nums = [2,3,1,1,4]
输出:true

解释:

  • 从下标 0 跳 1 步到下标 1
  • 从下标 1 跳 3 步到下标 4(终点)

示例 2:

text 复制代码
输入:nums = [3,2,1,0,4]
输出:false

解释:

  • 无论如何都会被卡在下标 3(最大跳跃为 0),无法继续前进

二、问题本质分析

这个问题本质是在问:

在每一步都有限制跳跃长度的情况下,能否通过合理选择跳跃位置,最终覆盖到数组的最后一个下标?

它具有以下特点:

  • 不要求最少步数
  • 只关心「是否能到达终点」
  • 每个位置的选择会影响后续的可达范围

三、解法一:贪心算法(推荐)

1. 核心思想

始终维护当前能到达的最远位置 maxReach

  • 从左到右遍历数组
  • 每到一个位置 i,如果 i > maxReach,说明当前位置无法到达,直接返回 false
  • 否则更新最远可达位置:
text 复制代码
maxReach = max(maxReach, i + nums[i])

只要在遍历过程中,maxReach 能覆盖到最后一个下标,就说明可以到达终点。


2. 贪心思维流程图(Mermaid)





开始:maxReach = 0
遍历数组 i 从 0 到 n-1
i > maxReach ?
返回 false
更新 maxReach = max(maxReach, i + nums[i])
maxReach >= n-1 ?
返回 true


3. 为什么贪心是正确的?

  • 我们并不关心"从哪里跳",只关心"最远能跳到哪里"
  • 每一步选择当前能跳得最远的位置,一定不会比其他选择更差
  • 一旦出现某个位置不可达,后面的所有位置都不可达

4. Java 实现代码(贪心)

java 复制代码
class Solution {
    public boolean canJump(int[] nums) {
        int maxReach = 0;

        for (int i = 0; i < nums.length; i++) {
            // 如果当前位置已经无法到达
            if (i > maxReach) {
                return false;
            }
            // 更新最远可达位置
            maxReach = Math.max(maxReach, i + nums[i]);
        }
        return true;
    }
}

5. 复杂度分析

指标 复杂度
时间复杂度 O(n)
空间复杂度 O(1)

四、解法二:动态规划(理解用,不推荐)

1. 核心思想

定义一个布尔数组:

text 复制代码
dp[i] 表示:是否能够跳到位置 i

状态转移:

text 复制代码
dp[i] = 存在某个 j < i,使得 dp[j] == true 且 j + nums[j] >= i

2. 动态规划状态转移示意图

0
1
2
3
4

只要某个位置可以由前面任意一个可达位置跳到,就标记为 true


3. Java 实现代码(DP)

java 复制代码
class Solution {
    public boolean canJump(int[] nums) {
        int n = nums.length;
        boolean[] dp = new boolean[n];
        dp[0] = true;

        for (int i = 1; i < n; i++) {
            for (int j = 0; j < i; j++) {
                if (dp[j] && j + nums[j] >= i) {
                    dp[i] = true;
                    break;
                }
            }
        }
        return dp[n - 1];
    }
}

4. 复杂度分析

指标 复杂度
时间复杂度 O(n²)
空间复杂度 O(n)

5. 为什么不推荐?

  • 数据规模大时容易超时
  • 贪心算法能用更低的复杂度解决同样问题

五、两种解法对比总结

Jump Game
贪心算法
思路简单
一次遍历
O(n) 时间
面试首选
动态规划
思路直观
状态转移清晰
O(n²) 时间
不适合大规模


  • 不要纠结"怎么跳",只关注"能跳多远"
  • 一旦当前位置超过最远可达范围,直接失败
  • 贪心是该题的最优解法
相关推荐
sqyno1sky1 天前
代码动态生成技术
开发语言·c++·算法
圣保罗的大教堂1 天前
leetcode 1727. 重新排列后的最大子矩阵 中等
leetcode
superior tigre1 天前
347 前k个高频元素
数据结构·算法·leetcode
2401_853576501 天前
C++中的策略模式变体
开发语言·c++·算法
m0_528174451 天前
C++中的策略模式实战
开发语言·c++·算法
MicroTech20251 天前
突破非幺正演化难题:MLGO微算法科技研发概率量子算法实现虚时间演化新路径
科技·算法·量子计算
Sagittarius_A*1 天前
霍夫变换:几何特征检测与量化验证【计算机视觉】
图像处理·人工智能·opencv·算法·计算机视觉·霍夫变换
计算机安禾1 天前
【C语言程序设计】第30篇:指针与字符串
c语言·开发语言·c++·算法·visualstudio·visual studio code·visual studio
信奥胡老师1 天前
GESP 2026年3月C++三级(二进制回文串)
开发语言·c++·算法
小年糕是糕手1 天前
【35天从0开始备战蓝桥杯 -- 刷题包】
c语言·jvm·数据结构·c++·算法·蓝桥杯