Day68(贪心算法)

134、加油站

根据示例2可知:

1、rest=gas[i]-cost[i]>0才可以作为出发点。 所以假设当前start=0为出发点,若gas[0]-cost[0]<0 则出发点就变成start=1(start=i+1),出发点变了,那么rest也要重置为0。

2、如果rest=gas[i]-cost[i]>0,那么剩余油量就持续加:即rest+=gas[i]-cost[i]。

3、gas的总和-cost的总和<0 返回-1,所以在遍历的时候要计算 total+=gas[i]-cost[i]

即在遍历的过程中剩余油量【rest+=gas[i]-cost[i];】必须始终≥0,才有机会环绕数组一周。

class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
        //gas.length==cost.length
        //gas的总和<cost的总和 返回-1 -----totalSum(gas)-totalSum(cost)<0
        //1.rest=gas[i]-cost[i]>0 
       
        int rest=0;//剩余油量
        int total=0;//总的油量
        int start=0;
        for(int i=0;i<gas.length;i++){
            rest+=gas[i]-cost[i];
            total+=gas[i]-cost[i];//判断
            if(rest<0){
                start=i+1;//换下一个加油站作为初始点
                rest=0;//如果剩余油量<0 就说明当前这个加油站不适合初始点,那么就重置剩余油量为0
            }
        }
        if(total<0) return -1;
        return start;
    }
}

135、分发糖果 

n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。

你需要按照以下要求,给这些孩子分发糖果:

  • 每个孩子至少分配到 1 个糖果。
  • 相邻两个孩子评分更高的孩子会获得更多的糖果。

请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。

​​​​​​分发糖果 (贪心思想,线性复杂度,清晰图解) - 分发糖果 - 力扣(LeetCode) (leetcode-cn.com) 题目中:相邻两个孩子评分更高的孩子会获得更多的糖果的意思如下

同时满足左规则和右规则

分发糖果: 

数组:1225432
起始:1111111
左遍历1212111
右遍历1114321

右遍历中:4比3大,所以在他的糖果的基础上+1。同理5比4大,在4的糖果的基础上+1

class Solution {
    public int candy(int[] ratings) {
        int left []=new int [ratings.length];
        int right[]=new int [ratings.length];
        Arrays.fill(left, 1);
        Arrays.fill(right,1);

        //左遍历
        for(int i=0;i<ratings.length;i++){
            if(i+1<ratings.length&&ratings[i+1]>ratings[i]){
                left[i+1]=left[i]+1;
            }
        }

        //右遍历
        for(int i=ratings.length-1;i>=0;i--){
            if(i-1>=0&&ratings[i-1]>ratings[i]){
                right[i-1]=right[i]+1;
            }
        }

        //取左遍历和右遍历对应学生糖果数的最大值 
        //这样则 同时满足左规则和右规则————即得到每个同学的最少糖果数量。
        int sum=0;
        for(int i=0;i<ratings.length;i++){
            sum+=Math.max(left[i],right[i]);
        }
        return sum;
    }
}

 452、用最少数量的箭引爆气球

学习数组排序的重写方式:

​​​​​​(2条消息) java comparator 升序、降序、倒序从源码角度理解_山鬼谣me的博客-CSDN博客_comparator 倒序

    //必须同时写这三个if条件来return 1、-1、0

    //升序
    if(o1>o2){
       return 1;//o1>o2 返回1就是正序
    }else if(o1<o2){
       return 1;
    }else{
       return 0;
    }
         
    
    //降序
    if(o1>o2){
       return -1;//o1>o2 返回-1就是倒序
    }else if(o1<o2){
       return 1;
    }else{
       return 0;
    }
         

一维数组:利用Arrays.sort重写的话,数组要用Integer

  二维数组:利用Arrays.sort重写的话,

①以行为数组来进行 行的正排序  o1[0]>o2[0]

 ②以列为数组进行列的正排序

 二者的排序结果:

如果以行的数来进行正排序,有重复的话,那么就按数组定义的顺序进行输出eg:先输出[2,9]再输出 [2,8],是因为定义二维数组的时候,[2,9]在[2,8]的前面。同理以列的数来进行正排序

很简明的思路:将二维数组进行排序。只要第一行、第二列的数值大于第二行第一列的数值,那么就可以一箭击2【所以应该以列为排序o1[1]>o2[1] 顺序进行排序】。注意:至少用1箭来击破气球

class Solution {
      public int findMinArrowShots(int[][] points) {
        if (points.length == 0) {
            return 0;
        }
        Arrays.sort(points, new Comparator<int[]>() {
            public int compare(int[] point1, int[] point2) {
                if (point1[1] > point2[1]) {
                    return 1;
                } else if (point1[1] < point2[1]) {
                    return -1;
                } else {
                    return 0;
                }
            }
        });
        
        int n = points.length;
        int pos = points[0][1];
        int res = 1;
        for (int i = 1; i < n; i++) {
            if (points[i][0] > pos){
                pos = points[i][1];
                res++;
            }
        }
        return res;
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值