【算法题讲解】45. 跳跃游戏 II

题解

function jump(nums: number[]): number {
    if(nums.length<=1) return 0;
    let steps:number=0;
    let maxReach:number=0;//当前能跳到的最远
    let nextMax:number=0;//下一个叶子能跳到的最远
    for(let i=0;i<nums.length;i++){
        nextMax = Math.max(i+nums[i],nextMax);
        if(i===maxReach){
            steps++;
            maxReach = nextMax;
            if(maxReach>=nums.length-1) break;
        }
    }
    return steps;
};

青蛙的贪心策略是:每一步都选能让自己下次跳得最远的荷叶


故事背景:青蛙跳荷叶

想象你是一只青蛙,站在一条河的起点(nums[0]),河面上漂浮着一串荷叶(数组 nums),每个荷叶上写着一个数字,表示你从这个荷叶上最多能跳多远(nums[i] 步)。你的目标是用 最少的跳跃次数 跳到最后一个荷叶(nums[n-1])。题目保证你一定能跳到终点。

比如,荷叶是 [2,3,1,1,4]

  • 站在第 0 个荷叶(2),能跳 2 步。
  • 站在第 1 个荷叶(3),能跳 3 步。
  • 最后要到达第 4 个荷叶(4 的位置)。

贪心策略:站得高望得远

青蛙有个绝招:它不想每次都随便跳,而是希望每跳一步都能尽量靠近终点。为此,它会:

  1. 先看看当前能跳多远:站在一个荷叶上,试探所有能跳到的荷叶,看哪片能让它下次跳得更远。
  2. 跳到“最佳中转站”:每一步跳到当前范围内能看到的最远位置。
  3. 数跳跃次数:每次跳到一个新的“边界”时,记一次跳。

我们用两个“望远镜”帮助青蛙:

  • 当前望远镜(maxReach):记录当前跳跃次数下,青蛙能摸到的最远荷叶。
  • 下一跳望远镜(nextMaxReach):试探下一次跳跃能看到的最远荷叶。

冒险开始:一步步跳

输入:[2,3,1,1,4]

目标:从下标 0 跳到下标 4,用最少步数。

出发点

  • 青蛙站在荷叶 0(数字 2),跳跃次数 steps = 0
  • 当前望远镜 maxReach = 0(还没跳,暂时只能到自己这)。
  • 下一跳望远镜 nextMaxReach = 0

第 1 步:试探第一跳

  • 青蛙站在荷叶 0(2),能跳 2 步,试探能到哪儿:
    • 下标 0 + 2 = 2,能跳到荷叶 2(1)。
  • 更新下一跳望远镜:nextMaxReach = max(0, 2) = 2
  • 当前位置(0)达到边界(maxReach = 0),必须跳了!
    • 跳跃次数 steps = 1
    • 把下一跳的范围给当前望远镜:maxReach = 2
  • 青蛙跳到荷叶 1(3),但我们关心的是范围,先继续看。

第 2 步:站在荷叶 1(3)试探

  • 从下标 1,能跳 3 步:1 + 3 = 4。
  • 更新下一跳望远镜:nextMaxReach = max(2, 4) = 4(能到终点了!)。
  • 当前位置(1)还没到边界(maxReach = 2),继续试探。

第 3 步:到达边界,准备第二跳

  • 青蛙走到下标 2,当前望远镜 maxReach = 2,正好是边界。
  • 需要再跳一次:
    • 跳跃次数 steps = 2
    • 更新当前望远镜:maxReach = nextMaxReach = 4
  • 这时 maxReach = 4 已经覆盖终点(下标 4),可以停了!

结果

  • 青蛙用了 2 次跳跃:从 0 跳到 1,再从 1 跳到 4。
  • 输出:2

再试一个例子:[2,3,0,1,4]

出发点

  • 荷叶 0(2),steps = 0, maxReach = 0, nextMaxReach = 0

第 1 步

  • 下标 0,能跳到 2:nextMaxReach = 2
  • 边界到了(i = 0, maxReach = 0):steps = 1, maxReach = 2

第 2 步

  • 下标 1(3),能跳到 1 + 3 = 4:nextMaxReach = 4
  • 下标 2,边界到了(i = 2, maxReach = 2):steps = 2, maxReach = 4
  • maxReach = 4 覆盖终点,结束。

结果2


为什么这么跳最少?

青蛙的贪心策略是:每一步都选能让自己下次跳得最远的荷叶。想象你在玩跳远游戏,你不会随便跳一小步,而是会挑一个能让你后续冲刺更远的中转站。这样,虽然每步不一定跳到终点,但总的跳跃次数会被压缩到最少。

  • 不需要所有路线:青蛙不用试每条路(比如从 0 到 2 再到 4),那样太麻烦。它只关心“从当前能到的荷叶里,哪个能让我下次跳最远”。
  • 边界更新:每次到边界(maxReach)时,青蛙必须跳,而这一跳会把“下一跳能到的最远距离”变成新的边界。

代码再看一眼

function jump(nums: number[]): number {
    if (nums.length <= 1) return 0;
    let steps = 0, maxReach = 0, nextMaxReach = 0;
    for (let i = 0; i < nums.length - 1; i++) {
        nextMaxReach = Math.max(nextMaxReach, i + nums[i]); // 试探下次最远
        if (i === maxReach) { // 到边界,跳!
            steps++;
            maxReach = nextMaxReach;
            if (maxReach >= nums.length - 1) break;
        }
    }
    return steps;
}
  • maxReach 是青蛙当前的地盘。
  • nextMaxReach 是青蛙用望远镜看到的下个目标。
  • 到边界(i === maxReach)就跳一步,更新地盘。

总结:像青蛙一样聪明

这个算法就像青蛙跳荷叶:站得高望得远,每步都挑最佳落脚点。虽然不试所有路,但通过“贪心”选择最优中转站,保证跳跃次数最少。希望这个故事让你对算法有画面感了吧!有什么不明白的再问我哦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值