day34 贪心 | 1005,134,135

  • 1005.K次取反后最大化的数组和
    • 按照一定的策略,先绝对值排序,再负数修正,最后对绝对值最小的数进行替换,再求和
  • 134. 加油站
    • ​​​​​​​判断是否可以从i 到达i + 1
    • 判断gas总量是否大于cost
  • 135. 分发糖果
    • ​​​​​​​采用两次遍历计算糖果数

package algor.trainingcamp;

import java.util.Arrays;
import java.util.stream.IntStream;

/**
 * @author lizhe
 * @version 1.0
 * @description: k次取反后的最大值
 * @date 2023/5/8 07:44
 *
 * 1. 先按照绝对值进行从大到小排序
 * 2. 从前到后遍历 如果发现有负数,优先变成正数
 * 3. 如果k还没有用完 变换最后一个数,再求和
 */
public class LeetCode1005 {
    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){
                k--;
                nums[i] = -nums[i];
            }
        }

        while(k > 0){
            k--;
            nums[nums.length - 1] = -nums[nums.length - 1];
        }

        return Arrays.stream(nums).sum();
    }
}
package algor.trainingcamp;

/**
 * @author lizhe
 * @version 1.0
 * @description:
 *
 * 在一条环路上有 n个加油站,其中第 i个加油站有汽油gas[i]升。
 *
 * 你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1个加油站需要消耗汽油cost[i]升。
 * 你从其中的一个加油站出发,开始时油箱为空。
 *
 * 给定两个整数数组 gas 和 cost ,如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1 。如果存在解,则 保证 它是 唯一 的。
 *
 * 来源:力扣(LeetCode)
 * 链接:https://leetcode.cn/problems/gas-station
 * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
 *
 * @date 2023/5/8 07:53
 *
 * 车从i站能开到i+1。
 * 所有站里的油总量要>=车子的总耗油量。
 */
public class LeetCode134 {
    public int canCompleteCircuit(int[] gas, int[] cost) {
        int cur = 0;
        int startIdx = 0;
        int total = 0;
        for(int i = 0;i < gas.length;i++){
            //判断: 车从i站能开到i+1
            cur += gas[i] - cost[i];
            //判断: 所有站里的油总量要>=车子的总耗油量。
            total += gas[i] - cost[i];
            //重新开始
            if(cur < 0){
                startIdx = i + 1;
                cur = 0;
            }
        }

        return total < 0 ? - 1 : startIdx;
    }
}
package algor.trainingcamp;

/**
 * @author lizhe
 * @version 1.0
 * @description: TODO
 * @date 2023/5/8 08:06
 *
 * 老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分。
 *
 * 你需要按照以下要求,帮助老师给这些孩子分发糖果:
 *
 * 每个孩子至少分配到 1 个糖果。
 * 相邻的孩子中,评分高的孩子必须获得更多的糖果。
 * 那么这样下来,老师至少需要准备多少颗糖果呢?
 *
 * 1. 如果前一位比后一位分数高,则糖果 + 1
 */
public class LeetCode135 {
    class Solution {
        public int candy(int[] ratings) {
            if(ratings == null || ratings.length == 0){
                return 0;
            }
            int[] nums = new int[ratings.length];//记录每一位孩子得到的糖果数
            nums[0] = 1;
            //先正序遍历,如果后一位比前一位高分,就给比前一位多1的糖果,否则给1
            for(int i = 1; i < ratings.length; i++){
                if(ratings[i] > ratings[i-1]){
                    nums[i] = nums[i-1] + 1;
                }else {
                    nums[i] = 1;
                }
            }
            //在倒叙遍历,如果前一位比后一位高分并且得到的糖果小于或等于后一位,就给前一位孩子比后一位孩子多一个糖果
            for(int i = ratings.length -2 ; i >= 0; i--){
                if(ratings[i] > ratings[i+1] && nums[i] <= nums[i+1]){
                    nums[i] = nums[i+1] +1;
                }
            }
            int count = 0;
            for(int i : nums){
                count +=i;
            }
            return count;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值