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


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

  1. 按绝对值从大到小排序,然后贪心:先变绝对值大的且为负数的
  2. 这里学习一下:Lambda表达式中,是对于Integer类型的数组排序的。
        int[] nums = new int[]{1,2,3};
        Integer[] arr = new Integer[nums.length];
        for (int i = 0; i < nums.length; i++) {
            arr[i] = nums[i];
        }
        Arrays.sort(arr, (a, b) -> (b - a));//从大到小排序
        Arrays.sort(arr, (a,b) -> (Math.abs(b)-Math.abs(a));//按绝对值从大到小排序
    public int largestSumAfterKNegations(int[] nums, int k) {
        Integer[] arr= new Integer[nums.length];
        for (int i = 0; i < nums.length; i++) {
            arr[i] = nums[i];
        }

        Arrays.sort(arr,(a,b)->(Math.abs(b)-Math.abs(a)));//按绝对值从大到小排序,然后先变绝对值大的

        for(int i=0;i<arr.length;i++){
            if(k>0&&arr[i]<0){
                k--;
                arr[i]=arr[i]*-1;
            }
        }
        if(k>0&&k%2==1){
            arr[arr.length-1]*=-1;
        }
        int sum=0;
        for(int i=0;i<arr.length;i++){
            sum += arr[i];
        }

        return sum;
    }

11分钟

二、134. 加油站

  1. 先加油,再消耗。
  2. 一旦curSum小于零,说明[0, i]区间都不能作为起始位置,那么起始位置从i+1算起,再从0计算curSum。
    public int canCompleteCircuit(int[] gas, int[] cost) {
        int curSum = 0;
        int totalSum = 0;
        int start = 0;
        for (int i = 0; i < gas.length; i++) {
            curSum += gas[i]-cost[i];
            totalSum += gas[i]-cost[i];
            if (curSum<0) {
                start = i+1;
                curSum=0;
            }
        }
        if (totalSum<0) return -1;
        else return start;

    }

39分钟

三、135. 分发糖果

  1. 需要考虑两边的情况。先确定一边,再确定另一边。
  2. 分两个阶段
    1、起点下标1 从左往右,只要 右边 比 左边 大,右边的糖果=左边 + 1
    2、起点下标 ratings.length - 2 从右往左, 只要左边 比 右边 大,此时 左边的糖果应该 取本身的糖果数(符合比它左边大) 和 右边糖果数 + 1 二者的最大值,这样才符合 它比它左边的大,也比它右边大
  3. 易错点:candy[i]=candy[i-1]+1;而不是candy[i]+=1;是比左边大1。
    public int candy(int[] ratings) {
        int[] candy = new int[ratings.length];
        Arrays.fill(candy,1);
        for(int i=1;i<candy.length;i++){
            if(ratings[i]>ratings[i-1]){
                // candy[i]+=1;
                candy[i]=Math.max(candy[i-1]+1;//注意这里
            }
        }
        for(int i=candy.length-2;i>=0;i--){//注意是从后面开始遍历
            if(ratings[i]>ratings[i+1]){
                candy[i]=Math.max(candy[i], candy[i+1]+1);
            }
        }
        int num=0;
        for(int i=0;i<candy.length;i++){
            num+=candy[i];
        }
        return num;
    }

20分钟

总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值