860.柠檬水找零
讲解链接:代码随想录-860.柠檬水找零
public boolean lemonadeChange(int[] bills) {
// 手里的零钱数量
int[] balance = new int[4];
for (int i = 0; i < bills.length; i++) {
// 需要给客户的钱
int giveChange = bills[i] - 5;
int start = 1;
// 循环手里的余额,从大的开始给,因为题目里能给客户的钱最大的为10,所以直接从下标1开始
while (giveChange > 0 && start >= 0) {
// 当前纸币下标对应的金额
int amount = (start + 1) * 5;
// 如果找的零小于纸币、纸币数量小于等于0,就递减,用更小的纸币。
if (giveChange < amount || balance[start] <= 0) {
start--;
continue;
}
giveChange -= amount;
balance[start]--;
}
// 如果手里的钱用完了,还是没找开,就返回false
if (giveChange > 0) {
return false;
}
balance[bills[i] / 5 - 1]++;
}
return true;
}
406.根据身高重建队列
讲解链接:代码随想录-406.根据身高重建队列
贪心
public int[][] reconstructQueue(int[][] people) {
// 根据身高降序;如果身高相同,根据序号升序。
Arrays.sort(people, (a, b) -> {
if (a[0] == b[0]) return a[1] - b[1];
else return b[0] - a[0];
});
// 按照顺序遍历,身高高的人会被先插入指定下标,矮的后插入指定下标,
// 这样就会排在身高高的前面,保证序号正确。
LinkedList<int[]> list = new LinkedList<>();
for (int i = 0; i < people.length; i++) {
list.add(people[i][1], people[i]);
}
// 注意转换为数组的流操作,不记得就循环吧。
return list.toArray(new int[list.size()][]);
}
暴力破解
public int[][] reconstructQueue(int[][] people) {
int[][] result = new int[people.length][];
// 身高从低到高排序
Arrays.sort(people, (a, b) -> a[0] - b[0]);
for (int i = 0; i < result.length; i++) {
for (int j = 0; j < people.length; j++) {
if (people[j] == null) continue;
int[] p = people[j];
int count = 0;
for (int k = 0; k < i; k++) {
int[] r = result[k];
if (r[0] >= p[0]) {
count++;
}
}
if (count == p[1]) {
result[i] = people[j];
people[j] = null;
break;
}
}
}
return result;
}
452.用最少数量的箭引爆气球
public int findMinArrowShots(int[][] points) {
// 根据气球直径的开始坐标从小到大排序,这里有边界值,直接用-法会溢出
Arrays.sort(points, (a, b) -> {
if (a[0] < b[0]) {
return -1;
} else {
return 1;
}
});
int count = 1; // points 不为空至少需要一支箭
for (int i = 1; i < points.length; i++) {
if (points[i][0] > points[i - 1][1]) { // 气球i和气球i-1不挨着,注意这里不是>=
count++; // 需要一支箭
} else { // 气球i和气球i-1挨着
points[i][1] = Math.min(points[i][1], points[i - 1][1]); // 更新重叠气球最小右边界
}
}
return count;
}
总结
好难