贪心算法专题(五):覆盖范围的艺术——「跳跃游戏」

哈喽各位,我是前端小L。

欢迎来到贪心算法专题第五篇! 想象一下,你站在一个长长的走廊里,地面上标着数字。每个数字代表你在当前位置最多 能向前跳几步(你可以跳满,也可以只跳一步)。 你的目标很简单:判断你能否从起点一直跳到终点?

这道题容易陷入的一个误区是:纠结于"我是跳 1 步好,还是跳 2 步好?"。 如果我们去模拟每一种跳法,那这就变成回溯问题了,复杂度会很高。

贪心算法告诉我们:别纠结具体跳几步,只看你最远能覆盖到哪!

力扣 55. 跳跃游戏

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

题目分析:

  • 输入 :非负整数数组 nums

  • 规则nums[i] 代表你在位置 i 的最大跳跃长度。

  • 目标:判断是否能到达最后一个下标。

例子 1: [2, 3, 1, 1, 4]

  • 在下标 0(数值2):最远能覆盖到下标 2。

  • 我们走到下标 1(数值3):最远能覆盖到下标 1 + 3 = 4

  • 既然能覆盖到 4(即终点),那就返回 true

例子 2: [3, 2, 1, 0, 4]

  • 在下标 0(数值3):最远覆盖到 3。

  • 在下标 1(数值2):最远覆盖到 1 + 2 = 3

  • 在下标 2(数值1):最远覆盖到 2 + 1 = 3

  • 在下标 3(数值0):最远覆盖到 3 + 0 = 3

  • 无论如何都跨不过下标 3 这个坎,到不了终点 4。返回 false

核心思维:维护"最大覆盖范围"

我们要把问题转化为:在这个覆盖范围内,我能不能把覆盖范围进一步扩大?

  1. Cover : 我们维护一个变量 cover,表示当前最远 能走到的下标。初始时,我们在起点,cover = 0

  2. 移动 :我们在 0cover 的范围内遍历每一个位置 i

    • 注意 :我们只能在 cover 范围内移动!如果你当前的位置 i 已经超过了 cover,说明你根本跳不到这儿,游戏结束。
  3. 更新 :对于遍历到的位置 i,我们计算这一跳能达到的最远距离:i + nums[i]

    • 如果 i + nums[i] 比当前的 cover 还要大,我们就更新 cover
  4. 判定 :一旦 cover >= nums.size() - 1(终点下标),说明终点已经被覆盖了,直接返回 true

贪心策略: 不管我怎么跳,我每一步都尽可能去更新最大的覆盖范围。只要终点在这个范围内,我就赢了。

算法流程

  1. cover = 0

  2. 如果数组只有一个元素,直接返回 true

  3. 遍历 i0nums.size() - 2(其实只需要遍历到 cover 即可,但为了代码简单,我们用循环控制):

    • 关键约束 :只有当 i <= cover 时,我们才能站在 i 上。

    • 贪心更新cover = max(cover, i + nums[i])

    • 提前结束 :如果 cover >= nums.size() - 1,返回 true

  4. 循环结束后,如果还没返回 true,说明到不了,返回 false

代码实现 (C++)

C++

复制代码
#include <vector>
#include <algorithm>

using namespace std;

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int cover = 0; // 当前能覆盖到的最远下标
        
        // 只有一个元素,肯定能到
        if (nums.size() == 1) return true;

        // 注意:i 只能在 cover 范围内移动
        // 虽然循环写的是 i <= cover,但 cover 是在动态增长的
        for (int i = 0; i <= cover; i++) {
            // 更新覆盖范围
            cover = max(cover, i + nums[i]);
            
            // 如果覆盖范围已经包含了终点
            if (cover >= nums.size() - 1) {
                return true;
            }
        }
        
        // 跑完所有能跑的地方,还是没覆盖到终点
        return false;
    }
};

深度复杂度分析

  • 时间复杂度:O(N)

    • 我们最多遍历数组一次。
  • 空间复杂度:O(1)

    • 只需要一个变量 cover

总结:格局打开

这道题展示了贪心算法的一种**"宏观视角"。 我们没有去纠结微观的"第一步跳几米,第二步跳几米",而是直接审视"势能"**(覆盖范围)。

  • 只要我的势能足够大,能罩住终点,那具体怎么跳,总归是有办法的。

下一题预告:跳跃游戏 II

现在难度升级了! 如果在上一题的基础上,我保证一定能跳到终点 ,但我要求你求出最少跳几步能到?

这时候,"最大覆盖范围"这个单一指标就不够用了。我们需要两个指标:"当前这一步最远能到哪""下一步最远能到哪"。 这道题是贪心算法中逻辑稍微复杂一点的题目,准备好烧脑了吗?

下期见!

相关推荐
前端小L2 小时前
贪心算法专题(六):步步为营的极速狂飙——「跳跃游戏 II」
算法·游戏·贪心算法
HMS Core2 小时前
《地铁跑酷》接入HarmonyOS SDK,显著优化游戏启动体验
游戏·华为·harmonyos
谈笑也风生2 小时前
经典算法题型之排序算法(一)
算法·排序算法
叫我:松哥2 小时前
基于django的新能源汽车租赁推荐分析系统,包括用户、商家、管理员三个角色,协同过滤+基于内容、用户画像的融合算法推荐
python·算法·机器学习·pycharm·django·汽车·echarts
xu_yule6 小时前
算法基础(数论)—费马小定理
c++·算法·裴蜀定理·欧拉定理·费马小定理·同余方程·扩展欧几里得定理
girl-07267 小时前
2025.12.28代码分析总结
算法
NAGNIP9 小时前
GPT-5.1 发布:更聪明,也更有温度的 AI
人工智能·算法
NAGNIP9 小时前
激活函数有什么用?有哪些常用的激活函数?
人工智能·算法
元亓亓亓10 小时前
LeetCode热题100--416. 分割等和子集--中等
算法·leetcode·职场和发展