算法训练营day35_贪心算法(3.7)
860.柠檬水找零
开个哈希表,或者数组,因为就仨;
给5不用找,给10找1个5,给20找1个10and1个5或者3个5;
给20优先找10块的,因为5块的普适性高(先把5的找没了,给10块找不了了,我刚开始直接没想这边,还寻思着这不简单暴力么hh)
class Solution {
public:
unordered_map<int,int> M;
bool lemonadeChange(vector<int>& bills) {
M.clear();
int n=bills.size();
for(int i=0;i<n;i++){
if(bills[i]==10){
if(!M[5]) return false;
M[5]-=1;
}
if(bills[i]==20){
if(M[10]>=1&&M[5]>=1){
M[10]-=1;
M[5]-=1;
}
else if(M[5]>=3){
M[5]-=3;
}
else return false;
}
M[bills[i]]++;
}
return true;
}
};
406.根据身高重建队列
这道题我思路出来了,觉得操作vector里元素换位置很麻烦,否定了,害;
先把身高从大到小,如果身高相同2关键字从小到大;(这一步就是先确定身高这个维度,看了视频才知道这什么两个维度先确定一个维度,我做的时候思路没这么规范,就是觉得先确定一个比较好);
然后就是操作vector里元素,插入删除,直接新开一个空的vector往里插入(这个刚开始没想到!)
class Solution {
public:
static bool cmp(vector<int> t1,vector<int> t2){
if(t1[0]!=t2[0]) return t1[0]>t2[0];
return t1[1]<t2[1];
}
vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
sort(people.begin(),people.end(),cmp);
vector<vector<int>> ans;
for(int i=0;i<people.size();i++){
int pos=people[i][1];
ans.insert(ans.begin()+pos,people[i]);
}
return ans;
}
};
452.用最少的箭引爆气球
经典题,区间排序;
这道题说是俩维度吧,因为箭无限长,其实就一个维度;从x轴左边往右看,尽量让一个箭多射几个球,肯定是射右端点比较好(这算局部吧),以此可以得出最少的箭射穿所有气球(这算全局吧,思路规范hhh);
所有区间按照右端点从小到大排;然后遍历一遍,如果l比上一个箭last大,就得更新射的点了;
有几个注意点:
last初始化设为-1e10,因为这个里面是有负数,-1就不太靠谱了,表示不了初始;
重写cmp的时候记得加&,说实话之前打比赛没注意过根本,力扣这种都是参数传数组提醒我了,还是要注意一下的,这道题不加&要超时;
class Solution {
public:
static bool cmp(vector<int> &t1,vector<int> &t2){
return t1[1]<t2[1];
}
int findMinArrowShots(vector<vector<int>>& points) {
sort(points.begin(),points.end(),cmp);
int ans=0;
long long last=-1e10;
for(auto i:points){
int l=i[0],r=i[1];
if(last==-1e10||l>last){
ans++;
last=r;
}
}
return ans;
}
};