目录
题目连接:860.柠檬水找零
思路
找零会出现以下情况:
①5美元,直接收下
②10美元,找一个5美元
③20美元,找一个10美元和一个5美元;或者找三个5美元
也就是说只有②③情况会出现找不开的情况,所以只需要在遍历bills数组时,不断记录5美元和10美元的数量即可。如果遍历完数组没有出现5美元和10美元数量不够的情况,就说明能够找开。题目不难,只要分析清楚上述三种情况即可。
代码
class Solution {
public:
bool lemonadeChange(vector<int>& bills) {
int five = 0; // 记录五美元的数量
int ten = 0; // 记录十美元的数量
for (int a : bills) {
// 五美元直接收下,数量加一
if (a == 5) {
five++;
}
// 十美元,要找五美元
else if (a == 10) {
// 没有五美元可找了,返回false
if (five <= 0)
return false;
five--;
ten++;
}
// 二十美元,首先判断能否找十美元和五美元
// 如果不行,就找三个五美元
// 只有上述两种情况,如果都不行就说明找不开
else if (a == 20) {
// 因为十美元只能找二十美元,所以优先判断
if (ten >= 1 && five >= 1) {
ten--;
five--;
} else if (ten <= 0 && five >= 3) {
five -= 3;
} else
return false;
}
}
return true;
}
};
题目连接:406.根据身高重建队列
思路
有两个维度,身高h和前面身高大于等于自己身高的人数k,一定要先确定一个维度,然后用另一个维度来进行排序。
选定身高为第一个维度,让所有人按照从高到低的顺序排列,如果身高相同则k小的人站在前面。这样就一定能保证前面的人不比后面的人矮。
然后按照k进行排序,因为已经按照身高排序,此时k是多少,就让他前面站几个人即可。
代码
class Solution {
public:
// 定义排序规则,按h从大到小,h相等的人,k小的在前面
static bool cmp(const vector<int>& a, const vector<int>& b) {
if (a[0] == b[0])
return a[1] < b[1]; // k小的在前面
return a[0] > b[0];
}
vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
sort(people.begin(), people.end(), cmp); // 按身高排序
list<vector<int>> que; // list底层实现是链表,插入元素时间复杂度低
for (int i = 0; i < people.size(); i++) {
int position = people[i][1]; // k值即位置
auto it = que.begin();
// 找到列表中插入元素的位置
while (position--) {
it++;
}
que.insert(it, people[i]); // 插入元素
}
// 按照函数返回类型返回结果
return vector<vector<int>>(que.begin(), que.end());
}
};
题目连接:452. 用最少数量的箭引爆气球
思路
需要注意的是每个气球的区间更新问题,具体见代码注释
代码
class Solution {
public:
// 定义排列规则,按照起始位置,从小到大
static bool cmp(const vector<int>& a, const vector<int>& b) {
return a[0] < b[0];
}
int findMinArrowShots(vector<vector<int>>& points) {
if (points.size() == 0)
return 0;
sort(points.begin(), points.end(), cmp); // 排序
int result = 1; // 有气球,则最少一支箭
for (int i = 1; i < points.size(); i++) {
// 当前气球的起点大于上一个气球的终点
if (points[i][0] > points[i - 1][1]) {
result++;
}
// 如果两个气球挨着或者重叠,则更新当前气球的终点为最小的右边界
// 如果不更新,则会出现1和2重叠,2和3重叠,但是1和3不重叠
// 只记录一支箭的情况,实际应该是需要两支
//
else {
points[i][1] = min(points[i][1], points[i - 1][1]);
}
}
return result;
}
};
总结
①贪心算法已经做了一些题了,但遇到新题时还是没有明确的思路,多练多复习
②双维度排列问题,需要逐步分析,不可一起考虑
③重叠区间问题,注意区间的更新