代码随想录算法训练营Day32|122.买卖股票的最佳时机 II、55. 跳跃游戏、45.跳跃游戏 II

目录

122.买卖股票的最佳时机 II

前言

思路

算法实现

55. 跳跃游戏

思路

算法实现

45.跳跃游戏 II

前言

思路

算法实现

总结


122.买卖股票的最佳时机 II

题目链接

文章链接

前言

         本题要求只能持有一支股票,根据每日股票的价格控制股票的买入和卖出获取最大利润。

思路

        可以将最终利润分解,分解为每天为单位的维度,假如第 0 天买入,第 3 天卖出,那么利润为:prices[3] - prices[0],相当于(prices[3] - prices[2]) + (prices[2] - prices[1]) + (prices[1] - prices[0]),那么根据 prices 可以得到每天的利润序列:(prices[i] - prices[i - 1]).....(prices[1] - prices[0])。

        只要我们收集每天的正利润区间就是股票买卖的区间,我们只需要关注最终利润,而不需记录区间。

        局部最优:收集每天的正利润;全局最优:求得最大利润。局部最优可以推出全局最优,找不出反例,试一试贪心!

算法实现

class Solution {
public:
    int maxProfit(vector& prices) {
        int result = 0;
        for (int i = 1; i < prices.size(); i++){
            result += max(prices[i] - prices[i - 1], 0);
        }
        return result;
    }
};

55. 跳跃游戏

题目链接

文章链接

思路

        对于每个位置跳几步不要过于细化和具体,其实跳几步无所谓,关键在于可跳的覆盖范围!有点类似于窗口的思想,那么这个问题就转化为跳跃覆盖范围究竟可不可以覆盖到终点!

        每次移动取最大跳跃步数(得到最大的覆盖范围),每移动一个单位,就更新最大覆盖范围。贪心算法局部最优解:每次取最大跳跃步数(取最大覆盖范围),整体最优解:最后得到整体最大覆盖范围,看是否能到终点

算法实现

class Solution {
public:
    bool canJump(vector& nums) {
        int cover = 0;
        if (nums.size() == 1) return true;
        for (int i = 0; i <= cover; i++){
            cover = max(cover,i + nums[i]);
            if (cover >= nums.size() - 1) return true;
        }
        return false;
    }
};

        i 每次移动只能在 cover 的范围内移动,每移动一个元素,cover 得到该元素数值(新的覆盖范围)的补充,让 i 继续移动下去。而 cover 每次只取 max(该元素数值补充后的范围, cover 本身范围)。如果 cover 大于等于了终点下标,直接 return true 就可以了。

45.跳跃游戏 II

题目链接

文章链接

前言

        本题可以继承上一题求最大覆盖范围的思路,但是在具体处理上还要复杂一些。

思路

         本题要求的是到达最后一个位置的最少跳跃次数,从覆盖范围出发,覆盖范围内一定是可以跳到的,以最小的步数增加覆盖范围,覆盖范围一旦覆盖了终点,得到的就是最少步数!

        这里需要统计两个覆盖范围,当前这一步的最大覆盖和下一步最大覆盖。如果移动下标达到了当前这一步的最大覆盖最远距离了,还没有到终点的话,那么就必须再走一步来增加覆盖范围,直到覆盖范围覆盖了终点。

算法实现

class Solution {
public:
    int jump(vector& nums) {
        if (nums.size() == 1) return 0;
        int curDistance = 0;
        int nextDistance = 0;
        int ans = 0;
        for (int i = 0; i < nums.size(); i++){
            nextDistance = max(nextDistance, nums[i] + i);
            if (i == curDistance){
                ans++;
                curDistance = nextDistance;
                if (nextDistance >= nums.size() - 1) return ans;
            }
        }
        return false;
    }
};

总结

        贪心算法的题目确实思路比较难想,有点费脑子。

你可能感兴趣的:(游戏)