Leetcode 第45题:Jump Game II--跳跃游戏II(C++)

题目地址:Jump Game II


题目简介:

给定一个非负整数数组,最初位于数组的第一个位置。数组中的每个元素代表你在该位置可以跳跃的最大长度,目标是使用最少的跳跃次数到达数组的最后一个位置。

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

说明:假设你总是可以到达数组的最后一个位置。
 


题目解析:

1、超时的动态规划:

结合上题,纪录到达第i个位置的最小跳数,根据上一跳的位置和跳数更新,算法时间复杂度O(n^{2}

class Solution {
public:
    int jump(vector<int>& nums) {
        int len = nums.size();
        if (len <= 1)
            return 0;
        int dp[len];
        memset(dp, 127, sizeof(dp));
        dp[0] = 0;
        for (int i = 0; i < len - 1; i++)
        {
            int temp = nums[i];
            for (int j = 1; j <= temp; j++)
            {
                if (i + j < len)
                    dp[i + j] = min(dp[i + j], dp[i] + 1);
                else if(i + j == len - 1)
                    return dp[len - 1];
                else
                    break;
            }
        }
        return dp[len - 1];
    }
};

2、贪婪算法(参考地址

在每个位置上,扫描范围内最大的数字,确定可以到达的最大的边界。当扫描位置达到了最大的边界时,说明需要继续向下走一步,更新当前所能达到的最大边界,直到扫描完所有的数据。例如:

  • 初始位置上的数字为2,他能达到的范围是橙色的。又3 + 1 > 2 + 2,选择位置为3的数字,跳到4。

  • 但是只按照上述的方法去找,很可能会遇到只有0可以跳的位置。所以需要对每一个节点都需要考虑,例如上图。
  • 结合动态规划的思想,当扫描位置达到了上一次更新的边界时,说明需要达到当前位置的最小跳数已经确定。那么只需继续向下考虑,找到下一个所能达到的最大边界,并确定在当前边界内最小的跳数。

总的来说,就是先确定一个范围,在这个范围内,所有点的点都可以达到,然后在这个范围内的点去找最远的距离的点。

C++版:

class Solution {
public:
    int jump(vector<int>& nums) {
        int end = 0, maxPosition = 0, steps = 0;
        for(int i = 0; i < nums.size() - 1; i++)
        {
            maxPosition = max(maxPosition, nums[i] + i); 
            if(i == end)
            {
                end = maxPosition;
                steps++;
            }
        }
        return steps;
    }
};
static auto _=[](){ios::sync_with_stdio(false);return 0;}();

关于代码的最后一句的加速原理:解析 static auto x = []() { std::ios::sync_with_stdio(false);std::cin.tie(nullptr);return 0;}()

猜你喜欢

转载自blog.csdn.net/chao_shine/article/details/89445114