力扣 hot100 Day71

45. 跳跃游戏 II

给定一个长度为 n0 索引 整数数组 nums。初始位置为 nums[0]

每个元素 nums[i] 表示从索引 i 向后跳转的最大长度。换句话说,如果你在索引 i 处,你可以跳转到任意 (i + j) 处:

  • 0 <= j <= nums[i]
  • i + j < n

返回到达 n - 1 的最小跳跃次数。测试用例保证可以到达 n - 1

cpp 复制代码
class Solution {
public:
    int jump(vector<int>& nums) {
        int n = nums.size();
        int jumps = 0;
        int current_end = 0;
        int farthest = 0;
        
        for (int i = 0; i < n - 1; ++i) {
            farthest = max(farthest, i + nums[i]);
            if (i == current_end) {
                jumps++;
                current_end = farthest;
                if (current_end >= n - 1) {
                    break;
                }
            }
        }        
        return jumps;
    }
};

处理逻辑是,在上一题的基础上,记录当前的跳跃次数以及当前所能达到的最远点,只有在达到最远点后,才增加跳跃次数。

这里的次数,其实记录的是到达current_end所需最小次数,所以终止条件是,current_end大于等于n-1。

很容易陷入的牛角尖是,每一步都走最远未必次数最少。这是正确的,但这里的算法逻辑是,在当前跳跃范围内,尽可能探索下一步所能到达的最远范围,只有在不得不跳时,才次数加一。

jumps++时,算法并不关心"具体跳到哪里",而是通过维护 current_endfarthest隐式决定了跳跃策略​