代码随想录算法训练营day35 | 860.柠檬水找零,406.根据身高重建队列,452. 用最少数量的箭引爆气球

代码随想录算法训练营day35 | 860.柠檬水找零,406.根据身高重建队列,452. 用最少数量的箭引爆气球

  • 860.柠檬水找零
  • 406.根据身高重建队列
  • 452. 用最少数量的箭引爆气球


860.柠檬水找零

教程视频:https://www.bilibili.com/video/BV12x4y1j7DD/?spm_id_from=333.788&vd_source=ddffd51aa532d23e6feac69924e20891
代码随想录算法训练营day35 | 860.柠檬水找零,406.根据身高重建队列,452. 用最少数量的箭引爆气球_第1张图片
代码随想录算法训练营day35 | 860.柠檬水找零,406.根据身高重建队列,452. 用最少数量的箭引爆气球_第2张图片

有如下三种情况:
情况一:账单是5,直接收下。
情况二:账单是10,消耗一个5,增加一个10
情况三:账单是20,优先消耗一个10和一个5,如果不够,再消耗三个5
class Solution {
    public boolean lemonadeChange(int[] bills) {
        int five = 0;
        int ten = 0;

        for (int i = 0; i < bills.length; i++) {
            if (bills[i] == 5) {
                five++;
            } else if (bills[i] == 10) {
                five--;
                ten++;
            } else if (bills[i] == 20) {
                if (ten > 0) {
                    ten--;
                    five--;
                } else {
                    five -= 3;
                }
            }
            if (five < 0 || ten < 0) return false;
        }
        
        return true;
    }
}

406.根据身高重建队列

教程视频:https://www.bilibili.com/video/BV1EA411675Y/?spm_id_from=333.788&vd_source=ddffd51aa532d23e6feac69924e20891
代码随想录算法训练营day35 | 860.柠檬水找零,406.根据身高重建队列,452. 用最少数量的箭引爆气球_第3张图片本题类似135.分发糖果,如果两个维度一起考虑一定会顾此失彼。
按照身高h来排序,身高一定是从大到小排(身高相同的话则k小的站前面),让高个子在前面。此时我们可以确定身高维度了,前面的节点一定都比本节点高!那么只需要按照k为下标重新插入队列就可以了。

所以在按照身高从大到小排序后:
局部最优: 优先按身高高的people的k来插入。插入操作过后的people满足队列属性
全局最优: 最后都做完插入操作,整个队列满足题目队列属性

class Solution {
    public int[][] reconstructQueue(int[][] people) {
        //按照身高降序排序,如果身高相等k按照升序排列
        Arrays.sort(people, (p1, p2)->{//这是Comprator的简化,返回正数调换位置
            if(p1[0]==p2[0]){return p1[1]-p2[1];}
            return p2[0]-p1[0];
        });

        LinkedList<int[]> que = new LinkedList<>();
        for(int i=0; i<people.length; i++){
            que.add(people[i][1],people[i]);//这里巧妙地使用了LinkedList的add方法模拟了元素插入过程
        }

        return que.toArray(new int[people.length][]);
    }
}

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

教程视频:https://www.bilibili.com/video/BV1SA41167xe/?spm_id_from=333.788&vd_source=ddffd51aa532d23e6feac69924e20891
代码随想录算法训练营day35 | 860.柠檬水找零,406.根据身高重建队列,452. 用最少数量的箭引爆气球_第4张图片代码随想录算法训练营day35 | 860.柠檬水找零,406.根据身高重建队列,452. 用最少数量的箭引爆气球_第5张图片

局部最优:当气球出现重叠,一起射,所用弓箭最少。
全局最优:把所有气球射爆所用弓箭最少。
为了让气球尽可能的重叠,需要对数组进行排序。下面题解是使用气球起始位置排序实现的,也可以使用终止位置排序,只是遍历顺序需要调整。
【注意】这里排序时可能会溢出,需要使用Integer内置比较方法Integer.comare(a,b)

class Solution {
    public int findMinArrowShots(int[][] points) {
        //没有气球时,不需要射击
        if(points.length==0)return 0;
        //按照左边界排序
        // 使用Integer内置比较方法,不会溢出
        Arrays.sort(points,(p1, p2)->Integer.compare(p1[0],p2[0]));
        
        int shot = 1;//有气球时,至少射击一次
        for(int i=1;i<points.length;i++){
            //上一个右边界与下一个左边界不重合需要一次射击
            if(points[i-1][1]<points[i][0]){
                shot++;
            }else{
                //重合则更新最小右边界
                points[i][1] = Math.min(points[i-1][1],points[i][1]);
            }
        }
        return shot;
    }
}

你可能感兴趣的:(代码随想录训练营,算法,数据结构,java)