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

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

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

按绝对值从大到小排序

再从前开始反转负数,这样反转过来的都是大的正数

如果反转次数还剩余奇数次,就反转最后一个数(绝对值最小的)

偶数次,不用反转

class Solution {
    public int largestSumAfterKNegations(int[] nums, int k) {
        nums = IntStream.of(nums)
		     .boxed()
		     .sorted((o1, o2) -> Math.abs(o2) - Math.abs(o1))
		     .mapToInt(Integer::intValue).toArray();
        int len = nums.length;
        for (int i = 0; i < len; i++) {
            //从前向后遍历,遇到负数将其变为正数,同时K--
            if (nums[i] < 0 && k > 0) {
                nums[i] = -nums[i];
                k--;
            }
        }

        // 如果K还大于0,那么反复转变数值最小的元素,将K用完
        if (k % 2 == 1) nums[len - 1] = -nums[len - 1];
        return Arrays.stream(nums).sum();

    }
}
  • 时间复杂度: O(nlogn)
  • 空间复杂度: O(1)

2. 加油站

134. 加油站 - 力扣(LeetCode)

curSum < 0 意味着之前的所有点都不能作为起点

只能从下一个作为起点,再进行尝试

        如果当前点已经是最后一个了,i+1超过数组长度(for循环结束,totalSum < 0,会返回 -1)

如果totalSum < 0 意味着不存在满足条件的起点

totalSum > 0 则一定存在满足条件的起点 (通过curSum寻找符合的起点)

也可以先求得totalSum,判断是否有起点

class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
        int length = gas.length;

        int curSum = 0;
        int start = 0;
        int totalSum = 0;

        for(int i = 0; i < length; i++){
            totalSum += gas[i] - cost[i];
            curSum += gas[i] - cost[i];
            if(curSum < 0){
                curSum = 0;
                start = i + 1;
            }
        }
        
        if(totalSum < 0) 
            return -1;
        return start;
    
    }
}

3. 分发糖果 

135. 分发糖果 - 力扣(LeetCode)

  • 一次是从左到右遍历,只比较右边孩子评分比左边高的情况。

        更高,则右边=左边+1,否则 =1

  • 一次是从右到左遍历,只比较左边孩子评分比右边高的情况。

        更高,则左边 = 右边+1和之前结果取最大值(因为还要保证比它的左边大,所以不能比之前的结果小)否则不变

class Solution {
    public int candy(int[] ratings) {
        int length = ratings.length;
        int[] candy = new int[length];

        candy[0] = 1;
        for(int i = 1; i < length; i++){
            if(ratings[i] > ratings[i-1]){
                candy[i] = candy[i-1] + 1;
            }else
                candy[i] = 1;
        }

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

        int res = 0;
        for (int num : candy) {
            res += num;
        }

        return res;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值