#LeetCode 860. Lemonade Change
#LeetCode 860. 视频讲解:贪心算法,看上去复杂,其实逻辑都是固定的!LeetCode:860.柠檬水找零_哔哩哔哩_bilibili
如果收到的是5 或者10 的纸币,那么找零的选择是固定的,并不需要考虑贪心策略。所以贪心策略应用于收到20 的纸币时,这个时候的局部最优是先用10 和5 的纸币找零,因为5 可以用于给10 找零,所以全剧最优是可以对所有的柠檬水找零。
贪心算法代码:
class Solution {
public boolean lemonadeChange(int[] bills) {
int five = 0;
int ten = 0;
int twenty = 0;
for (int i = 0; i < bills.length; i++) {
if (bills[i] == 5) {
five ++;
}
else if (bills[i] == 10) {
if (five == 0) {
return false;
} else {
ten ++;
five --;
}
if (five < 0) {
return false;
}
}
else {
twenty++;
if (ten > 0 && five > 0) {
ten --;
five --;
}
else if (five >= 3) {
five -= 3;
}
else {
return false;
}
}
}
return true;
}
}
#LeetCode 406. Queue Reconstruction by Height
#LeetCode 406. 视频讲解:贪心算法,不要两边一起贪,会顾此失彼 | LeetCode:406.根据身高重建队列_哔哩哔哩_bilibili
第一个难点是理解题目... 理解题目后,需要考虑是先按照h 排序还是k 排序。观察正确排序的数组,k 是按照从小到大的顺序来排序的,代表的是前面有k 个大于等于当前h 的数字。再考虑按照h 排序,正确的方法是h 按照从大到小的顺序排序,这样再次按照k 进行插值,可以保证前面的数字是大于当前的h 的,也不会影响后面的数字的顺序,因为h 已经从大到小排序,放入前面的数字都比当前数字小。
Java 的算法中,用的是Arrays.sort 实现的,Lambda 表达式中,a - b 表达的是降序,b - a 表达的是升序。如果height 相同,那么就按照k 值升序排序,如果height 不同,那么直接按照降序排序。
使用队列来排序,可以根据index 和value 直接进行插值排序。在最后返回时需要将队列转换回数组返回。
贪心算法代码:
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[]> queue = new LinkedList<>();
for (int[] p: people) {
queue.add(p[1], p);
}
return queue.toArray(new int[people.length][]);
}
}
#LeetCode 452. Minimum Number of Arrows to Burst Balloons
#LeetCode 452. 视频讲解:贪心算法,判断重叠区间问题 | LeetCode:452.用最少数量的箭引爆气球_哔哩哔哩_bilibili
题目中的局部最优是当气球出现重叠,只用一支弓箭。全局最优是用最少的弓箭引爆所有气球。
本题的难点是如何记录重叠气球,思路是先将无序的气球按照左边节点值排序,将气球尽可能的相邻。判断两个相邻气球是否有重叠难度不大,如何判断三个气球是否相邻,这是本题中需要考虑的要点。解题方法是用point[i - 1][0] 变量来记录右边界,每次都会更新右边界,用最小的值来代替右边边界的值。
贪心算法代码:
class Solution {
public int findMinArrowShots(int[][] points) {
if (points.length == 0) {
return 0;
}
Arrays.sort(points, (a,b) -> Integer.compare(a[0], b[0]));
int result = 1;
for (int i = 1; i < points.length; i++) {
if (points[i][0] > points[i-1][1]) {
result ++;
} else{
points[i][1] = Math.min(points[i][1], points[i-1][1]);
}
}
return result;
}
}