860.柠檬水找零
- 链接:代码随想录
5美元相当滴珍贵
- 解题思路:
情况一:账单是5,直接收下。
情况二:账单是10,消耗一个5,增加一个10
情况三:账单是20,优先消耗一个10和一个5,如果不够,再消耗三个5
所以对于前两种情况消耗都是固定的,贪心贪在第三步
public boolean lemonadeChange(int[] bills) {
int five = 0,ten = 0,twenty = 0;
for(int bill : bills){
//情况一
if(bill == 5){
five++;
}
//情况二
if(bill == 10){
if(five <= 0){
return false;
}
five--;
ten++;
}
//情况三
if(bill == 20){
//贪心:优先花10元
if(ten > 0 && five > 0){
ten--;
five--;
twenty++;
}else if(five >= 3){
five-=3;
twenty++;
}else{
return false;
}
}
}
return true;
}
406.根据身高重建队列
-
链接:代码随想录
-
解题思路:
两个维度:1. 身高;2.前面有几个人比自己大于等于高
①如果按照k来从小到大排序,排完之后,会发现k的排列并不符合条件,身高也不符合条件,两个维度哪一个都没确定下来。
因为如果按照k排序完之后,还需要修改k的值,就是k和h都没确定下来
②那么按照身高h来排序呢,身高一定是从大到小排(身高相同的话则k小的站前面),让高个子在前面。
只要身高确定下来之后,后边的元素随便向前边插入,都不会影响前面的k的排序,即确定了身高之后,在移动也不会改变k,只是调整符合k -
图像理解
按身高来做
public int[][] reconstructQueue(int[][] people) {
//λ表达式,传入的是数组
// Comparator<Integer[]> comparator = (a,b) -> {
// if(a[0] == b[0]){
// return a[1] - b[1];
// }
// return b[0] - a[0];
// };
//根据身高排好序,身高高的在前面
//大于0就交换
Arrays.sort(people,(a, b) -> {
if (a[0] == b[0]) return a[1] - b[1];//相等,k按从小到大拍
return b[0] - a[0];//身高按从大到小拍
});
//调整位置
LinkedList<int[]> que = new LinkedList<>();
for (int[] p : people) {
que.add(p[1],p);//按位置加入
}
return que.toArray(new int[people.length][]);
}
452. 用最少数量的箭引爆气球⭐️
- 题目链接:代码随想录
重叠问题
-
解题思路:
贪心:局部最优:当气球出现重叠,一起射,所用弓箭最少。全局最优:把所有气球射爆所用弓箭最少。
①先对数组进行排序,初始值置为1,因为最少有一次射箭
②判断边界是否重叠,如果重叠的话,那么跳过这次射箭,并且更新重叠的最小右边界,便于下一次判重叠区域
如果没有重叠的话,那么直接射箭次数加+1 -
图像理解:
public int findMinArrowShots(int[][] points) {
//从小到大排序
Arrays.sort(points, (a, b) -> {
return Integer.compare(a[0], b[0]);
});
int count = 1;//射箭的话直射一箭
for (int i = 1; i < points.length; i++) {
if(points[i][0] > points[i - 1][1]){
count++;
}else{//气球i和i-1是相邻的情况,更新最小重叠有边界
points[i][1] = Math.min(points[i][1], points[i - 1][1]);//更新重叠气球的最小边界
}
}
return count;
}