一句话总结:身高队列看起来不简单,实际上也很难。
原题链接:860 柠檬水找零
简单贪心思想即可。5元时加入cnt5,10元时cnt10++,cnt5--, 20元时则优先找零10元再找零5元,这样最后判断是否在一次找零后是否cnt5<0即可。
class Solution {
public boolean lemonadeChange(int[] bills) {
if (bills[0] != 5) return false;
int cntFive = 1, cntTen = 0;
int n = bills.length;
for (int i = 1; i < n; ++i) {
if (bills[i] == 5) ++cntFive;
else if (bills[i] == 10) {
++cntTen;
--cntFive;
} else {
if (cntTen > 0) {
--cntFive;
--cntTen;
} else cntFive -= 3;
}
if (cntFive < 0) return false;
}
return true;
}
}
原题链接:406 根据身高重建队列
先对数组按第一个元素h降序排列,如果数组的第一个元素相等,则对第二个元素升序排列。再将排序后的数组按照其第二个元素的优先级依次排列入队,返回即可。
class Solution {
public int[][] reconstructQueue(int[][] people) {
Arrays.sort(people, (a, b) -> {
if (a[0] == b[0]) return a[1] - b[1];
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,然后更新左右边界,否则仅更新左右边界为重叠部分即可。
class Solution {
public int findMinArrowShots(int[][] points) {
Arrays.sort(points, (a, b) -> Integer.compare(a[0], b[0]));
int ans = 1;
int start = points[0][0], end = points[0][1];
for (int[] point : points) {
if (point[0] > end) {
ans++;
start = point[0];
end = point[1];
} else {
start = Math.max(start, point[0]);
end = Math.min(end, point[1]);
}
}
return ans;
}
}