算法刷题Day 34 K次取反后最大化的数组和+加油站+分发糖果

Day 34 贪心算法

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

class Solution {
public:
    int largestSumAfterKNegations(vector<int>& nums, int k) {
        sort(nums.begin(), nums.end());
        int idx = 0;
        for (; idx < nums.size(); ++idx)
        {
            if (nums[idx] < 0 && k > 0)
            {
                nums[idx] = -nums[idx];
                k--;
            }
            else break;
        }

        sort(nums.begin(), nums.end()); // 这里需要重新排序一遍,因为前面调整了符号,所以现在最小值可能不是原来的最小正值
        if (k % 2)
        {
            nums[0] = -nums[0];
        }

        int sum = 0;
        for (auto num : nums)
        {
            sum += num;
        }

        return sum;
    }
};

代码随想录里面是按照绝对值从大到小进行排序的,这样就不用进行两次排序

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);

        for (auto &num : nums)
        {
            if (num < 0 && k > 0)
            {
                num = -num;
                k--;
            }
        }

        if (k % 2)
        {
            nums[nums.size() - 1] = -nums.back();
        }

        int sum = 0;
        for (auto num : nums)
        {
            sum += num;
        }

        return sum;
    }
};

134. 加油站

暴力解法

模拟的思想很重要,暴力解法模拟跑一圈的过程其实比较考验代码技巧的,要对while使用的很熟练。虽然会超时

class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        int totalGas = 0, totalCost = 0, len = gas.size();
        totalGas = accumulate(gas.begin(), gas.end(), 0);
        totalCost = accumulate(cost.begin(), cost.end(), 0);

        if (totalCost > totalGas) return -1;
        
        for (int i = 0; i < len; i++)
        {
            int rest = gas[i] - cost[i];
            int loop = (i + 1) % len;
            while (rest > 0 && loop != i)
            {
                rest += gas[loop] - cost[loop];
                loop = (loop + 1) % len;
            }

            if (rest >= 0 && loop == i)
            {
                return i;
            }
        }
        
        return -1;
    }
};

贪心算法

class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        int totalSum = 0, curSum = 0, start = 0;

        for (int i = 0; i < cost.size(); i++)
        {
            int rest = gas[i] - cost[i];
            curSum += rest;
            totalSum += rest;

            if (curSum < 0)
            {
                start = i + 1;
                curSum = 0;
            }
        }

        if (totalSum < 0) return -1;
        return start;
    }
};

135. 分发糖果

class Solution {
public:
    int candy(vector<int>& ratings) {
        vector<int> candies(ratings.size(), 1); // 注意:这里的初始值是1

        for (int i = 1; i < ratings.size(); i++)
        {
            if (ratings[i - 1] < ratings[i])
            {
                candies[i]++;
            }
        }

        for (int i = ratings.size() - 2; i >= 0; i--)
        {
            if (ratings[i + 1] < ratings[i])
            {
                candies[i] = max(candies[i + 1] + 1, candies[i]);
            }
        }

        return accumulate(candies.begin(), candies.end(), 0);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值