Hot100-Day30-T45跳跃游戏2

3 阅读2分钟

Day30[26/3/30]T45跳跃游戏2

给定一个长度为 n 的 0 索引整数数组 nums。初始位置在下标 0。

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

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

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

示例 1:

输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
     从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。

示例 2:

输入: nums = [2,3,0,1,4]
输出: 2

提示:

  • 1 <= nums.length <= 104
  • 0 <= nums[i] <= 1000
  • 题目保证可以到达 n - 1

解题思路

依旧是贪心算法,就是看我现在有这么多步可以选,我选哪一步之后,下一步可以走的更远。

举例,比如说对于 [2, 3, 1, 1, 4]

第一步肯定是第一个数字 2,那么意味着我下一次可以走下标 1 和 2,

那么我选 1 还是 2 呢?选 1 的话,再下一步可以走 3 格,那么下一步我最远可以抵达 1+3 = 4;而如果我选择 2 的话,在下一步就只可以走 1 格,也就是下一步最远可以抵达 2+1=3,所以选择 1。

也就是选择 max(i + nums[i]) 的情况。

然后下一次循环遍历范围就是 [i, i+nums[i]]

Code

#include <iostream>
#include <vector>

using namespace std;

class Solution
{
public:
    int jump(vector<int> &nums)
    {
        int step = 1;
        int left = 0;
        int right = 0;
        int max_range = 0; // 局部最优选择步的可达范围
        int max_index = 0; // 局部最优选择步的下标

        if (nums.size() == 1)
        {
            return 0;
        }

        // 先检查一步能不能结束
        if (nums[0] >= nums.size() - 1)
        {
            return 1;
        }

        do
        {
            int i = left;
            for (; i <= right; i++)
            {
                int range = i + nums[i];
                if (range >= max_range)
                {
                    max_range = range;
                    max_index = i;
                    if (max_range + 1 >= nums.size())
                    {
                        return step;
                    }
                }
            }
            step++;            // 跳跃步数计数
            left = max_index;  // 更新左边界
            right = max_range; // 更新右边界

        } while (left != right);
        return -1;
    }
};

auto main() -> int
{
    Solution sol;

    // vector<int> nums{2, 3, 1, 1, 4};
    // vector<int> nums{2, 3, 0, 1, 4};
    // vector<int> nums{0};
    // vector<int> nums{1};
    // vector<int> nums{1, 2};
    vector<int> nums{1, 2, 3};

    cout << "count = " << sol.jump(nums) << endl;
}