Day34 贪心算法 LeetCode 1005 134 135

54 阅读1分钟

1005. K 次取反后最大化的数组和

心得

  • 想的是正常排序后,然后再绝对值排序,不如开始就绝对值排序,一步到位

题解

  • 绝对值排序,贪心贪的是负绝对值最大
class Solution {
static bool cmp(int a, int b) {
    return abs(a) > abs(b);
}
public:
    int largestSumAfterKNegations(vector<int>& nums, int k) {
        sort(nums.begin(), nums.end(), cmp);
        int sum = 0;
        for (int i = 0; i < nums.size(); i++) {
            if (nums[i] < 0 && k > 0) {
                nums[i] *= -1;
                k--;
            }
        }
        if (k % 2 == 1) nums[nums.size() - 1] *= -1;
        for (int num : nums) {
            sum += num;
        }
        return sum;
    }
};

134. 加油站

心得

  • 写出了余量累加,但是找位置的时候,没想好,其实应该是再次贪心求累加和

题解

  • 贪心贪在余量的累加,如果小于0,一定跑不满,大于的话一定能跑满,然后就是找跑满的位置
  • 一旦遇到累加为负,则证明只能在后一个位置能跑完
class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        int curSum = 0;
        int totalSum = 0;
        int result = 0;
        for (int i = 0; i < gas.size(); i++) {
            curSum += gas[i] - cost[i];
            totalSum += gas[i] - cost[i];
            if (curSum < 0) { // 一旦小于0,下个位置才可能是
                result = i + 1;
                curSum = 0;
            }
        }
        if (totalSum < 0) return -1;
        return result;
    }
};

135. 分发糖果

心得

  • 考虑了两端开始的情况,但是对第二次求和没有做max比较,有可能第一次就已经满足条件了

题解

  • 左右分开考虑,注意可能第一次的时候已经满足了,所以需要max
class Solution {
public:
    int candy(vector<int>& ratings) {
        int result = 0;
        vector<int> candyVec(ratings.size(), 1);
        for (int i = 1; i < ratings.size(); i++) {
            if (ratings[i] > ratings[i - 1]) { // 从左到右
                candyVec[i] = candyVec[i - 1] + 1;
            }
        }
        for (int i = ratings.size() - 2; i >= 0; i--) { // 从右往左
            if (ratings[i] > ratings[i + 1]) {
                candyVec[i] = max(candyVec[i + 1] + 1, candyVec[i]);  // 从左到右可能已经满足了
            }
        }
        for (int x : candyVec) {
            result += x;
        }
        return result;
    }
};