860.柠檬水找零
贪心的策略就是给20的时候优先找10和5,其次找三个5.
class Solution {
public:
bool lemonadeChange(vector<int>& bills) {
int five=0,ten=0,twenty=0;
for(int bill:bills){
if(bill==5) five++;
else if(bill==10){
if(!five) return false;
five--;
ten++;
}else{
if(five&&ten){
five--;
ten--;
twenty++;
}else if(five>=3){
five-=3;
twenty++;
}else return false;
}
}
//如果都没有返回false就能找开
return true;
}
};
406.根据身高重建队列
和分发糖果切入点相同,这种有两个维度需要考虑的题目,就要先考虑一个维度,两个同时考虑一定会顾此失彼,本题我们先对身高进行排序,再根据k进行插入。
class Solution {
public:
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];
}
vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
sort(people.begin(),people.end(),cmp);
vector<vector<int>> queue;
for(int i=0;i<people.size();i++){
int pos=people[i][1];
queue.insert(queue.begin()+pos,people[i]);
}
return queue;
}
};
本题还有待优化。
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 res=1;
for(int i=1;i<points.size();i++){
if(points[i][0]>points[i-1][1]) res++;//只要有重叠就一定是用一支箭就可以射爆
//错因:应该是和上一个气球的右边界进行比较,写成了points[i][1]
else{
//更新右边界,以便知道下一个是否也可以用同一支箭射爆
points[i][1]=min(points[i-1][1],points[i][1]);
}
}
return res;
}
};
错因:判断有无重叠应该是当前区间的左边界和上一个气球的右边界进行比较,所以是i-1