训练营第三十七天|LeetCode1005、134、135

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

个人思路:很简单,先把数组里的元素按照绝对值大小排序,按照从大到小的顺序排序,排序之后遍历数组,将数组所有小于0的变成正数,如果小于0的数没变完,说明已经有了最大的和了,如果小于0的数变完了,但是K还有值,那就把最小的值反复变,怎么个反复变的方法,就是判断K 是奇数还是偶数,如果是奇数那就变一次,偶数就不用变了

代码

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();
        for(int i=0;i<nums.length;i++){
            if(nums[i]<0&&k>0){
                nums[i] = -nums[i];
                k--;
            }

        }
    if(k%2 == 1) nums[nums.length-1] = -nums[nums.length-1];
    return Arrays.stream(nums).sum();

    }
}

题目链接:134. 加油站 - 力扣(LeetCode)

个人思路:第一步,判断总油量是否大于总消耗量,如果小于,则直接返回-1;如果大于,则进入第二步

第二步,定义一个剩余量的概念,剩余量指的是当前加油站的油量,减去去往下一个加油站所消耗的油量,也就是gas[i]-cost[i]。

第三步,定义一个累加值,累加值指的是剩余量的总和,如果在遍历累加的过程中,累加值小于0,那么我们的索引下标加一,累加值清零,直到遍历完之后,返回索引下标值,为什么累加值为零时,索引下标值要加一?

首先我们要知道,如果累加值为负数,说明我们到不了目的加油站。而我们目前在做的就是去寻找能够跑完一圈的起点在哪里,因此,当加上当前这个值的时候累加值为负数,说明当前这个值是小于0的,也就是说,假如我选择当前这个值为起点,那么我跑不到下一个加油站,所以我要选择当前这个值的下一个值。

代码

class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
        int curSum=0;
        int totalSum=0;
        int index=0;
        for(int i=0;i<gas.length;i++){
            curSum +=gas[i]-cost[i];
            totalSum += gas[i]-cost[i];
            if(curSum<0){
                index = (i+1);
                curSum =0;
            }

        }
        if(totalSum <0) return -1;
        return index;

    }
}

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

个人思路:这题比较难,使用两次贪心,第一次局部最优是从左到右遍历,只比较右孩子大于左孩子的情况。第二次局部最优是从右到左遍历,只比较左孩子大于右孩子的情况

candyVec[i] = Math.max(candyVec[i+1]+1,candyVec[i]);
candyVec[i] = (ratings[i]>ratings[i-1])?candyVec[i-1]+1:1;

这两行代码为什么要这么写,有一个例子[1,3,4,5,2],输出是11

代码

class Solution {
    public int candy(int[] ratings) {
        int len = ratings.length;
        int[] candyVec = new int[len];
        candyVec[0] = 1;
        for(int i =1;i<len;i++){
            candyVec[i] = (ratings[i]>ratings[i-1])?candyVec[i-1]+1:1;
        }
        for(int i = len-2;i>=0;i--){
            if(ratings[i]>ratings[i+1]){
                candyVec[i] = Math.max(candyVec[i+1]+1,candyVec[i]);
            }
        }
        int ans=0;
        for(int i:candyVec){
            ans += i;
        }
        return ans;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值