代码随想录训练营day34|贪心算法3| 1005.K次取反后最大化的数组和|134加油站|135分发糖果

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

先对数组进行排序,然后对所有负数进行取反并计算总和,如果此时k已经用完,那么直接返回total,如果没用完,再对数组进行排序,找出此时的最小值,如果k为偶数,则返回total,如果为奇数则返回total-2*nums[i]

class Solution {
    public int largestSumAfterKNegations(int[] nums, int k) {
        int n = nums.length;
        int total=0;
        Arrays.sort(nums);
        for(int i=0;i<nums.length;i++){
            if(nums[i]<0 &&k>0){
                nums[i] =-1*nums[i];
                k--;
            }
            total+=nums[i];
        }
        Arrays.sort(nums);
        if(k==0){
            return total;
        }else{
            if(k%2==0){
                return total;
            }else{
                return total-2*nums[0];
            }
        }
    }
}

  134.加油站

一共有三种情况:

1. 如果汽油的总和小于消耗的总和,那么一定不能完成所以返回-1;

2. 因为我们在求情况1时是从0开始的,所以如果在这种情况下能够完成,我们返回0

3.如果0出发无法满足,我们在经过前两步的计算之后可以得到一个从0出发的情况下还需要多少油才能满足的值,然后从后往前依次增加每一个加油站能够补充的油,当min大于等于0时,就是唯一可能得解

class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
        int sum = 0;
        int min = 0;
        for (int i = 0; i < gas.length; i++) {
            sum += (gas[i] - cost[i]);
            min = Math.min(sum, min);
        }

        if (sum < 0) return -1;
        if (min == 0) return 0;

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

        return -1;
    }
}

135.分发糖果

先从左往右遍历,寻找右侧比左侧大的时候:numbers[i] = numbers[i-1]+1;

然后从右往左遍历,寻找左侧比右侧大的情况,这个时候有两种可能 这个位置的数等于右侧+1;或者这个位置本来就有数,但是更大,所以这个位置取最大值

class Solution {
    public int candy(int[] ratings) {
        int n = ratings.length;
        int []numbers = new int [n];
        numbers[0]=1;
        for(int i=1;i<ratings.length;i++){
            if(ratings[i]>ratings[i-1]){
                numbers[i] = numbers[i-1]+1;
            }else{
                numbers[i]=1;
            }
        }
        for(int i=ratings.length-2;i>=0;i--){
            if(ratings[i]>ratings[i+1]){
                numbers[i] = Math.max(numbers[i],numbers[i+1]+1);
            }
        }
        int sum =0;
        for(int i=0;i<ratings.length;i++){
            sum+=numbers[i];
        }

        return sum;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值