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²) 时间
不适合大规模


  • 不要纠结"怎么跳",只关注"能跳多远"
  • 一旦当前位置超过最远可达范围,直接失败
  • 贪心是该题的最优解法
相关推荐
踩坑记录1 小时前
leetcode hot100 74. 搜索二维矩阵 二分查找 medium
leetcode
月挽清风1 小时前
代码随想录第35天:动态规划
算法·动态规划
岛雨QA1 小时前
链表「Java数据结构与算法学习笔记3」
数据结构·算法
Sunsets_Red2 小时前
P8277 [USACO22OPEN] Up Down Subsequence P 题解
c语言·c++·算法·c#·学习方法·洛谷·信息学竞赛
汉克老师2 小时前
GESP2023年12月认证C++二级( 第三部分编程题(2) 小杨的H字矩阵)
c++·算法·矩阵·循环结构·gesp二级·gesp2级
_Li.2 小时前
Simulink-螺旋桨动力模块
人工智能·算法·机器学习
Charlie_lll2 小时前
力扣解题-438. 找到字符串中所有字母异位词
后端·算法·leetcode
奶茶树2 小时前
【数据结构】红黑树
数据结构·c++·算法
AI周红伟2 小时前
周红伟:OpenAI 首席运营官,尚未真正看到人工智能渗透到企业业务流程中
人工智能·算法·性能优化