860.柠檬水找零
题目链接:860. 柠檬水找零 - 力扣(LeetCode)
解题思路:
本题以为有什么更好的模拟思想,其实并没有。下面的for循环感觉逻辑还是不够清晰,而且三种面值的钱完全剋以用三个变量直接代表,搞了个数组反而变复杂了。
class Solution {
public boolean lemonadeChange(int[] bills) {
// 创建一个数组,存放不同面值钱的数量
int[] record = new int[3];
// 开始模拟
for(int i = 0; i < bills.length; i++){
int back = bills[i] - 5;
while(back > 0){
if(back > 10 && record[1] > 0){
back -= 10;
record[1]--;
}
while(back >= 5){
if(record[0] > 0){
back -= 5;
record[0]--;
}
else return false;
}
}
if(bills[i] == 5) record[0]++;
else if(bills[i] == 10) record[1]++;
System.out.println(record[0] + "," + record[1]);
}
return true;
}
}
这个题真是自己搞的越来越复杂- -简单的题暴力处理逻辑就好了
class Solution {
public boolean lemonadeChange(int[] bills) {
// 创建一个数组,存放不同面值钱的数量
int five = 0, ten = 0;
// 开始模拟
for(int i = 0; i < bills.length; i++){
if(bills[i] == 20){
if(ten > 0){
ten--;
five--;
}
else{
five -= 3;
}
} else if(bills[i] == 10){
five--;
ten++;
} else if(bills[i] == 5){
five++;
}
if(five < 0 || ten < 0) return false;
}
return true;
}
}
406.根据身高重建队列
题目链接:Loading Question... - 力扣(LeetCode)
解题思路:
记住这句话:遇到两个维度权衡的时候,一定要先确定一个维度,再确定另一个维度。否则会顾此失彼
排过序之后就有规律可循了。
例如:[7,0] [7,1] [6,1] [5,0] [5,2] [4,4]
拿[5,2]来举例,[5,2]前面一定都大于等于5,所以想要满足[5,2]中的2,那么[5,2]就需要插入到他前面插入完成数组的第3个位置。这样就能保证前面只有两个大于等于他的元素。后续再在他前面插入元素也没关系,因为是比它小的元素,不会对他产生影响
class Solution {
public int[][] reconstructQueue(int[][] people) {
// 先排序
Arrays.sort(people,(t1,t2) -> Integer.compare(t1[0],t2[0]) == 0? Integer.compare(t1[1],t2[1]): Integer.compare(t2[0],t1[0]));
List<int[]> ans = new LinkedList<>();
for(int[] p : people){
ans.add(p[1],p);
}
return ans.toArray(new int[people.length][]);
}
}
452.用最少数量的箭引爆气球
题目链接:452. 用最少数量的箭引爆气球 - 力扣(LeetCode)
解题思路:
先按照每个区间的起始位置进行排序,然后判断每个区间,是否和上一组区间有重叠,有重叠就认为可以用一个飞镖打爆,不用增加飞镖个数,如果没重叠,飞镖个数增加1,同时上一组气球的结束区间为这组区间中第一个区间的末尾。
这个想法的有问题的,当时只考虑到了[1,4] [2,5] 这种关系的区间,而没有考虑到[1,4] [2,3] 这种包含关系的区间,这种判断重叠区间的方法是不合理的。
curend = points[i][1];
class Solution {
public int findMinArrowShots(int[][] points) {
// 先将points按照第一个元素进行排序
Arrays.sort(points, (a, b) -> Integer.compare(a[0], b[0]));
int num = 1; // 飞镖个数
// 循环处理
int curend = points[0][1];
for(int i = 1; i < points.length; i++){
if(points[i][0] <= curend) continue;
else{ // 不能用同一个飞镖了
num++;
curend = points[i][1];
}
}
return num;
}
}
改进!要想清楚如何去处理区间的终止位置,curend代表的是已经重叠的几个区间的重叠部分的最大值。例如
[2,4] [2,5] [3,5] 那么这个curend = 4。
出现错误的原因还是因为没有考虑到区间包含的情况。
class Solution {
public int findMinArrowShots(int[][] points) {
// 先将points按照第一个元素进行排序
Arrays.sort(points, (a, b) -> Integer.compare(a[0], b[0]));
int num = 1; // 飞镖个数
// 循环处理
int curend = points[0][1];
for(int i = 1; i < points.length; i++){
if(points[i][0] <= curend){
curend = Math.min(curend, points[i][1]);
}
else{ // 不能用同一个飞镖了
num++;
curend = points[i][1];
}
}
return num;
}
}