Hot100-Day29-T55跳跃游戏

1 阅读2分钟

Day29[26/3/29]T55跳跃游戏

给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。

判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false

示例 1:

输入:nums = [2,3,1,1,4]
输出:true
解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。

示例 2:

输入:nums = [3,2,1,0,4]
输出:false
解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标。

提示:

  • 1 <= nums.length <= 104
  • 0 <= nums[i] <= 105

解题思路

记住,你只需要返回真假,所以不必找出一条实际可行的路径,只需要确定能不能做到就可以了。

思路是这样的,你第一次访问 nums[0] 确定下一次你可以访问哪些元素,比如说 nums[0] = 2 那么你下一次就可以走 nums[1], nums[2] 然后你再看这俩元素能够走多远,比如说 nums[1] = 6, nums[2] = 2 那么下一次你能达到的最远处是 nums[1+6] 你只需要不断的更新你能够访问的最远下标 ,每次更新时检查是否大于 nums.size() - 1 即可。

Code

#include <iostream>
#include <vector>

using namespace std;

class Solution
{
public:
    bool canJump(vector<int> &nums)
    {
        int max_reach = 0;
        int reach_index_left = 0;
        int reach_index_right = 0;

        if (nums.size() == 1)
            return true;

        do
        {
            cout << "L = " << reach_index_left << " R = " << reach_index_right << endl;

            for (int i = reach_index_left; i <= reach_index_right; i++)
            {
                if (i + nums[i] > max_reach)
                {
                    max_reach = i + nums[i];
                    if (max_reach + 1 >= nums.size())
                        return true;
                }
            }

            reach_index_left = reach_index_right;
            reach_index_right = max_reach;
        } while (reach_index_left < reach_index_right);

        return false;
    }
};

auto main() -> int
{
    // vector<int> nums{2,3,1,1,4};
    // vector<int> nums{1, 2, 3};
    // vector<int> nums{0};
    vector<int> nums{3, 2, 1, 0, 4};

    Solution sol;

    if (sol.canJump(nums))
        cout << "True" << endl;
    else
        cout << "False" << endl;
}