代码随想录算法训练营第三十三天|LeetCode1005 K次取反后最大化的数组和 、LeetCode134 加油站、LeetCode135 分发糖果

文章讲述了三种编程问题的解决策略:通过排序和取反操作最大化数组和;计算加油站油量分配满足需求的起始点;以及公平分配糖果给孩子们,确保每个人得到至少比他们右边的孩子多一颗糖果。
摘要由CSDN通过智能技术生成

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

思路:先将数组排序,然后将数组从最小值开始向后取反,直至数组都为正。如果K小于数组中负数的个数,取反后直接求和。如果大于数组中负数的个数,将取反后全为正的数组再次排序,然后对最小的元素取反剩余次数,再对数组求和。

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

134.加油站

思路:计算每个加油站处获取油量与向下一站去消耗油量的差,建立cursum和totalsum,从第一个加油站开始将油量差加入两个sum中,如果cursum为负,说明从前面i个节点开始,油都不够用,起点设置为i+1,cursum清零。继续循环,如果循环结束后,totalsum>=0,说明一定存在满足条件的加油站,return start,如果totalsum<0,说明没有满足条件的加油站,return -1。

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

    }
};

135.分发糖果

思路:先判断右边比左边好的孩子,右边孩子的糖果数目为左边数目+1,再判断左边比右边好的孩子,左边孩子的糖果数目为max(右边孩子数目+1,当前数目)。这样就都能满足题目要求。判断右边比左边好时,从前往后循环遍历孩子,判断左边比右边好时,从后往前循环遍历孩子。

class Solution {
public:
    int candy(vector<int>& ratings) {
        vector<int> cset(ratings.size(),1);
        //右边比左边大
        for(int i = 1;i<ratings.size();i++)
        {
            if(ratings[i-1]<ratings[i])
            {
                cset[i] = cset[i-1]+1;
            }
        }
        for(int i=ratings.size()-2;i>=0;i--)
        {
            if(ratings[i]>ratings[i+1])
            {
                cset[i] = max(cset[i],cset[i+1]+1);
            }
        }
        int sum=0;
        for(int i = 0;i<cset.size();i++)
        {
            sum+=cset[i];
        }
        return sum;
    }
};

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值