代码随想录训练营第三十四天1005.K次取反后最大化的数组和134. 加油站135. 分发糖果

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

题目链接 1005. K 次取反后最大化的数组和 - 力扣(LeetCode)

讲解链接 代码随想录 (programmercarl.com)

 思路还是比较明确的:先将最小的负数尽可能的转化为正数,并在之后判断几种可能出现的情况:

1、反转次数k有剩余,若是奇数,则把最小的数反转,若是偶数,则返回和

2、反转次数k无剩余,则直接返回。

这就要求了对于数组的排序有了一定的要求:即对数组进行绝对值排序:

    static bool cmp(int nums1,int nums2){
        return abs(nums1)>abs(nums2);
    }

        sort(nums.begin(),nums.end(),cmp);

同时本题需要注意,数组单个位置取反应该用*=-1,不然会报错。

剩下的就是简单的判断、反转,求和了。

134. 加油站

题目链接 134. Gas Station - 力扣(LeetCode)

讲解链接 代码随想录 (programmercarl.com)

 思考一阵之后对于本题的想法主要是求两个数组的对位差,并计算对位差的累加:

        for(int i=0;i<gas.size();i++){
            int temp=gas[i]-cost[i];
            cur+=temp;//对位差的累加
            if(cur<min){
                min=cur;//对位差累加的最低点
            }

        }

同时可能出现三种情况:

1、累加和小于0:根本跑不到,返回-1;

2、累加和大于零,且累加的最低点大于零,从零开始就可以跑完,全程油充足。

3、累加和大于零,但是累加的最低点小于零,此时需要从后往前(因为车是沿着数组从前往后跑,并逐个计量的)累加判断什么时候对位差的和能覆盖住累加最低点的负值,此时便可以选为开始节点

        if(cur<0)return -1;
        if(min>=0)return 0;
        for(int i=gas.size()-1;i>=0;i--){
            int res=gas[i]-cost[i];
            min+=res;
            if(min>=0)return i;
        }

135. 分发糖果

题目链接 135. 分发糖果 - 力扣(LeetCode)

讲解链接 代码随想录 (programmercarl.com)

 本体的思路十分新颖,由于每两个相邻孩子不同成绩就要成绩高的比成绩低的多的糖果所以对于高分的在左边以及高分的在右侧两种情况,这时,就需要转换思路不再是一个一个的从左到右每个孩子成绩左右比较判断,而是先从左到右挨个比较一次,再从右到左挨个比较一次,第一次只要右侧比左边大,就糖果加一,

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

        }

第二次从右往左挨个比较,若是左边的比右边的大,则左侧的糖果值就要是右侧糖果值加一与当前糖果值比较的较大者(因为左侧糖果值可能已经在从左往右过程中被变大,大于右侧,此时就不再用膨胀、也不能比右侧加一大了):

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

        }

整体来说还是很有难度、很难理解的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值