《代码随想录》刷题打卡day24:贪心算法part02

文章目录

【买卖股票的最佳时机II】

思路:局部最优:收集每天的正利润,全局最优:求得最大利润

c++ 复制代码
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int result = 0;
        // 只收集每天正利润,局部最优得到全局最优
        for(int i = 0; i < prices.size() - 1; i++){
            int diff = prices[i + 1] - prices[i];
            if(diff > 0){
                result += diff;
            }else continue;
        }
        return result;
    }
};
【55.跳跃游戏】

思路:

  • 跳几步无所谓,关键在于可跳的覆盖范围!

    不一定非要明确一次究竟跳几步,每次取最大的跳跃步数,这个就是可以跳跃的覆盖范围。

    这个范围内,别管是怎么跳的,反正一定可以跳过来。

  • 那么这个问题就转化为跳跃覆盖范围究竟可不可以覆盖到终点!

    每次移动取最大跳跃步数(得到最大的覆盖范围),每移动一个单位,就更新最大覆盖范围。

贪心算法局部最优解:每次取最大跳跃步数(取最大覆盖范围),整体最优解:最后得到整体最大覆盖范围,看是否能到终点

c++ 复制代码
class Solution {
public:
    bool canJump(vector<int>& nums) {
        int cover = 0;
        if (nums.size() == 1) return true; // 只有一个元素,就是能达到
        for (int i = 0; i <= cover; i++) { // 注意这里是小于等于cover
            cover = max(i + nums[i], cover);
            if (cover >= nums.size() - 1) return true; // 说明可以覆盖到终点了
        }
        return false;
    }
};
【跳跃游戏 II】

思路:还是覆盖范围,两个覆盖范围,一个curDistance判断,一个NextDistance更新

以最小的步数增加覆盖范围,覆盖范围一旦覆盖了终点,得到的就是最少步数!

这里需要统计两个覆盖范围,当前这一步的最大覆盖和下一步最大覆盖

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

c++ 复制代码
class Solution {
public:
    int jump(vector<int>& nums) {
        if(nums.size() == 1) return 0;
        int curDistance = 0; // 当前覆盖最远距离下标
        int ans = 0; // 记录走的最大步数
        int nextDistance = 0; // 下一步覆盖最远距离下标
        for(int i = 0; i < nums.size(); i++){
            nextDistance = max(nextDistance, i + nums[i]);
            if(i == curDistance){
                ans++; // 需要走下一步
                curDistance = nextDistance; // 更新当前覆盖最远距离下标
                if(nextDistance >= nums.size() - 1) break;
            }
        }
        return ans;
    }
};
【1005.K次取反后最大化的数组和】

思路:两次贪心,别怕麻烦

  • 第一步:将数组按照绝对值大小从大到小排序,注意要按照绝对值的大小
  • 第二步:从前向后遍历,遇到负数将其变为正数,同时K--
  • 第三步:如果K还大于0,那么反复转变数值最小的元素,将K用完
  • 第四步:求和
c++ 复制代码
class Solution {
static bool cmp(int a, int b) {
    return abs(a) > abs(b);
}
public:
    int largestSumAfterKNegations(vector<int>& A, int K) {
        sort(A.begin(), A.end(), cmp);       // 第一步
        for (int i = 0; i < A.size(); i++) { // 第二步
            if (A[i] < 0 && K > 0) {
                A[i] *= -1;
                K--;
            }
        }
        if (K % 2 == 1) A[A.size() - 1] *= -1; // 第三步
        int result = 0;
        for (int a : A) result += a;        // 第四步
        return result;
    }
};