day34打卡
860. 柠檬水找零
解法,贪心:局部最优:遇到账单20,优先消耗美元10,完成本次找零 -》全局最优:完成全部账单的找零。
- 遇到5,直接收下
- 遇到10,找一个5元
- 遇到20,优先找一张10和一张5,没有10元,找3张5元
class Solution {
public:
bool lemonadeChange(vector<int>& bills) {
int five = 0, ten = 0, twenty = 0;
for(auto& e : bills)
{
//情况1
if(e == 5) five++;
//情况2
if(e == 10)
{
if(five == 0) return false;
five--;
ten++;
}
//情况3
if(e == 20)
{
if(five > 0 && ten > 0)
{
five--;
ten--;
twenty++;
}
else if(five >= 3)
{
five -= 3;
twenty++;
}
else
{
return false;
}
}
}
return true;
}
};
406. 根据身高重建队列
解法,贪心:局部最优:优先按身高高的people的k来插入。插入操作过后的people满足队列属性 -》全局最优:最后都做完插入操作,整个队列满足题目队列属性
- 身高从大到小排(身高相同k小的站前面)
class Solution {
// 身高从大到小排(身高相同k小的站前面)
static bool cmp(const vector<int>& a, const vector<int>& b) {
if (a[0] == b[0]) return a[1] < b[1];
return a[0] > b[0];
}
public:
vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
sort(people.begin(), people.end(), cmp);
// list底层是链表实现,插入效率比vector高的多
list<vector<int>> queue;
for(int i = 0; i < people.size(); i++)
{
int pos = people[i][1];//插入位置的下标,也就是k
std::list<vector<int>>::iterator it = queue.begin();
while(pos--) it++;//找到插入位置
queue.insert(it, people[i]);
}
return vector<vector<int>>(queue.begin(), queue.end());
}
};
452. 用最少数量的箭引爆气球
解法,贪心:局部最优:当气球出现重叠,一起射,所用弓箭最少 -》全局最优:把所有气球射爆所用弓箭最少。
class Solution {
static bool cmp(vector<int>& a, vector<int>& b)
{
return a[0] < b[0];
}
public:
int findMinArrowShots(vector<vector<int>>& points) {
//按照气球起始位置排序
sort(points.begin(), points.end(), cmp);
//计算箭的数量
int ret = 1;//最少使用一个
for(int i = 1; i < points.size(); i++)
{
//判断气球是否重叠
//右边气球的左边界,是否大于,左边气球的右边界
if(points[i][0] > points[i-1][1])
{
//大于就多用一根箭
ret++;
}
else
{
//小于等于就使用同一根箭,
//并且缩小气球重叠边界范围(更新为左边的气球右边界和当前气球的右边界最小值)
points[i][1] = min(points[i][1], points[i-1][1]);
}
}
return ret;
}
};