leetcode 860
题目链接
找零 change
思路:
- 3种情况:
- 遇到
$5
:直接收下 - 遇到
$10
:找零5块 - 遇到
$20
:先尝试找零$10 + $5
,不行的话找零$5 x 3
- 遇到
- 贪心思想在哪里?
-
∵
\because
∵
$10
只能给$20
找零,而$5
可以给$10
和$20
找零 -
∴
\therefore
∴ 局部最优:
- 遇到
$20
,优先消耗$10
,完成本次找零
- 遇到
- 全局最优:
- 完成全部账单的找零
-
∵
\because
∵
class Solution {
public boolean lemonadeChange(int[] bills) {
int[] record = new int[3];
for (int x : bills) {
if (x == 5) {
++record[0];
continue;
}
else if (x == 10){
if (record[0] == 0)
return false;
else {
++record[1];
--record[0];
}
}
else if (x == 20) {
if (record[1] > 0 && record[0] > 0) {
--record[1];
--record[0];
++record[2];
}
else if (record[0] >= 3) {
++record[2];
record[0] -=3;
}
else
return false;
}
}
return true;
}
}
leetcode 406
题目链接
按照 height 排序
思路:
- like leetcode 135分发糖果,要处理2遍
- 对于
people[i] = [hi, ki]
,肯定是先处理身高顺序 - 思考身高顺序应该 decreasing 还是 increasing,发现用降序排后序更方便
- 按照身高排序之后,优先按身高高的people的k来插入,后序插入节点也不会影响前面已经插入的节点;height 相同的情况下,
k
小的排在前面 -
∴
\therefore
∴ 局部最优:
- 优先按
h
高的people
的k
来插入。插入操作过后的people
满足队列属性
- 优先按
- 全局最优:
- 最后都做完插入操作,整个队列满足题目队列属性
class Solution {
public int[][] reconstructQueue(int[][] people) {
Arrays.sort(people, (x, y) -> {
if (x[0] == y[0])
return x[1] - y[1];
return y[0] - x[0];
});
List<int[]> q = new LinkedList<>();
for (int[] x : people) {
q.add(x[1],x);
}
return q.toArray(new int[people.length][]);
}
}
leetcode 452
题目链接
重叠区间问题
思路:
- 寻找重叠气球最小右边界
- 局部最优:
- 当气球出现重叠,一起射,所用弓箭最少
- 全局最优:
- 把所有气球射爆所用弓箭最少
note:
Arrays.sort(points, (a, b) -> Integer.compare(a[0], b[0]));
,用Integer.compare()
方法排序,不用担心int
类型数值的溢出
class Solution {
public int findMinArrowShots(int[][] points) {
Arrays.sort(points, (a, b) -> Integer.compare(a[0], b[0]));
/*Arrays.sort(points, (a, b) -> {
return a[0] - b[0];
});*/
int num = 1;
for (int i = 1; i < points.length; ++i) {
//2个区间不重叠
if (points[i][0] > points[i - 1][1])
++num;
else
points[i][1] = Math.min(points[i][1], points[i - 1][1]); //更新最小右边界
}
return num;
}
}