【Hot 100】45. 跳跃游戏 II

发布于:2025-06-04 ⋅ 阅读:(15) ⋅ 点赞:(0)

请添加图片描述

  • 🙋‍♂️ 作者:海码007
  • 📜 专栏:算法专栏
  • 💥 标题:【Hot 100】45. 跳跃游戏 II
  • ❣️ 寄语:书到用时方恨少,事非经过不知难!

引言

跳跃游戏 II

  • 🎈 题目链接:
  • 🎈 做题状态:

dp解题

思路:
遍历nums数组,并且记录当前位置可以跳跃到的地方的最小步数,通过遍历 nums[i] 的值来更新每个位置的步数,并且需要记录最小步数。其实可以有一个优化技巧,就是记录minSteps数组此时更新到的最右侧边界索引。如果当前位置能超越这个索引就更新后面的步数值,如果超不过就不需要更新。

class Solution {
public:
    int jump(vector<int>& nums) {
        vector<int> minSteps(nums.size(), INT_MAX);
        minSteps[0] = 0;
        // 遍历nums,并更新每个位置跳跃所需要的最短距离。
        for(int i = 0; i < nums.size()-1; ++i)
        {
            int step = nums[i]; // 记录当前可以跳跃的步数

            for (int j = i + 1; j <= i + step && j < nums.size(); ++j)
            {
                minSteps[j] = min(minSteps[j],  minSteps[i] + 1); 
            }
        }

        return minSteps[nums.size()-1];
    }
};

贪心解题

贪心的思路理解起来还是有点费力的。

在每一次跳跃时,总是选择当前跳跃范围内能跳最远的位置,作为下一次跳跃的边界,以此保证跳跃次数最少。

虽然跳跃是“在到达边界 end 的时候触发”,但能跳多远,取决于之前所有点探索的最远跳跃距离 farthest;

换句话说:你起跳的位置未必是边界点本身,而是边界范围内跳得最远的那个位置。

👉 这正体现了贪心策略的精髓:不回头、只选择当前最优。

class Solution {
public:
    int jump(vector<int>& nums) {
        int steps = 0;       // 最终要返回的跳跃次数
        int end = 0;         // 当前这一跳的边界(跳到这就得起跳)
        int farthest = 0;    // 从当前范围中能跳到的最远位置

        // 注意:我们只遍历到 nums.size() - 2,因为最后一跳跳到终点时无需再跳
        for (int i = 0; i < nums.size() - 1; ++i)
        {
            // 更新当前能跳到的最远位置
            farthest = max(farthest, i + nums[i]);

            // 如果到达当前跳跃的边界,就必须跳一次
            if (i == end)
            {
                ++steps;         // 起跳!
                end = farthest; // 重新设置下一跳的边界
            }
        }

        return steps;
    }
};


网站公告

今日签到

点亮在社区的每一天
去签到