【代码随想录】day34

本文讨论了在编程中如何通过优化算法解决两个问题:1005K次取反后最大化数组和、134号加油站的燃油补给策略以及135号问题中糖果的公平分发。文章介绍了两种优化的解决方案:贪心算法和暴力法的应用。
摘要由CSDN通过智能技术生成

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


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

写的很混乱。。

class Solution {
public:
    int largestSumAfterKNegations(vector<int>& nums, int k) {
        sort(nums.begin(), nums.end());
        int res = 0;
        int index = 0;
        while (k > 0 && index < nums.size()) {
            if (nums[index] >= 0) {
                if (k % 2 == 1) {
                    if (index > 0 && nums[index] > nums[index-1]) {
                        nums[index-1] *= -1;
                    }
                    else {
                        nums[index] *= -1;
                    }
                    k = 0;
                }
                break;
            }
            nums[index] *= -1;
            index ++;
            k --;
        }
        if (k % 2 == 1) {
            nums[index-1] *= -1;
        }
        for (int num: nums) cout << num << " ";
        return accumulate(nums.begin(), nums.end(), 0);
    }
};

优化版:
贪心分两步。第一步:对绝对值大的负数优先取反;第二步:若k有剩余,用最小的正数消耗k。

class Solution {
public:
    static bool cmp(int a, int b) {
        return abs(a) > abs(b);
    }

    int largestSumAfterKNegations(vector<int>& nums, int k) {
        int n = nums.size();
        int res = 0;
        sort(nums.begin(), nums.end(), cmp);
        for (int i = 0; i < n && k > 0; i ++) {
            if (nums[i] < 0) {
                nums[i] *= -1;
                k --;
            }
        }
        if (k % 2 == 1) nums[n-1] *= -1;
        for (int num: nums) {
            res += num;
        }
        return res;
    }
};

二、134加油站

暴力法。。

class Solution {
public:
    int helper(vector<int>& gas, vector<int>& cost, int startIndex) {
        int num = 0;
        for (int i = startIndex; i < gas.size(); i ++) {
            num += gas[i];
            num -= cost[i];
            if (num < 0) {
                return 0;
            }
        }
        for (int i = 0; i < startIndex; i ++) {
            num += gas[i];
            num -= cost[i];
            if (num < 0) return 0;
        }
        return 1;
    }
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        if (gas.size() == 1 && gas[0] >= cost[0]) return 0;
        for (int startIndex = 0; startIndex < gas.size(); startIndex ++) {
            if (gas[startIndex] == cost[startIndex]) {
                continue;
            }
            if (helper(gas, cost, startIndex)) {
                return startIndex;
            }
        }
        return -1;
    }
};

贪心法:

class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        int n = gas.size();
        int curSum = 0;
        int startIndex = 0;
        int totalSum = 0;
        for (int i = 0; i < n; i ++) {
            curSum += gas[i] - cost[i];
            totalSum += gas[i] - cost[i];
            if (curSum < 0) {
                curSum = 0;
                startIndex = i + 1;
            }
        }
        if (totalSum < 0) {
            return -1;
        }
        return startIndex;
    }
};

三、135分发糖果

class Solution {
public:
    int candy(vector<int>& ratings) {
        vector<int> vec = {1};
        int n = ratings.size();
        for (int i = 1; i < n; i ++) {
            if (ratings[i] <= ratings[i-1]) {
                vec.push_back(1);
            }
            else {
                vec.push_back(vec[i-1] + 1);
            }
        }
        int res = vec.back();
        for (int i = n - 2; i >= 0; i --) {
            if (ratings[i] > ratings[i+1] && vec[i] <= vec[i+1]) {
                vec[i] = vec[i+1] + 1;
            }
            res += vec[i];
        }
        return res;
    }
};

  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值