贪婪
860. 柠檬水找零
代码:简单分析,逻辑清晰
class Solution {
public:
bool lemonadeChange(vector<int>& bills) {
int curcash = 0;
map<int,int>cash;
for(int i = 0; i < bills.size(); i++){
if(bills[i] == 5) cash[5]++;
if(bills[i] == 10){
if(cash[5] >= 1){
cash[10]++;
cash[5]--;
}
else return false;
}
if(bills[i] == 20){
if(cash[10]>=1&&cash[5] >= 1){
cash[20]++;
cash[5] = cash[5] - 1;
cash[10]--;
}
else if(cash[5] >= 3){
cash[5] = cash[5] - 3;
}
else return false;
}
cout<< cash[5]<<" "<<cash[10]<<" "<<cash[20]<<endl;
}
return true;
}
};
406. 根据身高重建队列
思路:两个维度考虑,先确定一个维度
1.按照身高降序排列,相同身高k小的排前面
2.排完序,进行插入操作
代码1:
class Solution {
public:
static bool cmp(vector<int> a,vector<int> b){
if(a[0] == b[0])return a[1] < b[1];
else return a[0] > b[0];
}
vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
sort(people.begin(),people.end(),cmp);
vector<vector<int>>que;
for( int i = 0; i < people.size(); i++){
int position = people[i][1];
que.insert(que.begin()+position,people[i]);//insert插入操作复杂度为n2,改成链表
}
return que;
}
};
代码2:插入操作采用list链表实现
class Solution {
public:
static bool cmp(vector<int> a,vector<int> b){
if(a[0] == b[0])return a[1] < b[1];
else return a[0] > b[0];
}
vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
sort(people.begin(),people.end(),cmp);
list<vector<int>>que;
for( int i = 0; i < people.size(); i++){
int position = people[i][1];
list<vector<int>>:: iterator it = que.begin();
while(position--){
it++;
}
que.insert(it,people[i]);//insert插入操作复杂度为n2,改成链表
}
return vector<vector<int>>(que.begin(),que.end());
}
};
452. 用最少数量的箭引爆气球
思路
1.标记射过的气球
2.为了让气球重叠,对数组进行排序:可以按其实位置排序,从前往后遍历数组,靠左尽可能让气球重复
3.重复气球中右边边界的最小值之间需要拉弓
射箭:
1.如果i的左边界大于i-1的右边界,则气球不重叠,要用弓箭point[i][1]<point[i-1][0]
2.重叠:i的左边界小于等于i-1的右边界point[i][0]>=point[i-1][0],
3.考虑是否多个气球重叠,更新i右边界,point[i][1]=min(point[i][1],point[i-1][1])
代码
class Solution {
public:
static bool cmp(vector<int> a, vector<int> b){
return a[0] < b[0];//按照起始位置升序
}
int findMinArrowShots(vector<vector<int>>& points) {
if(points.size() == 0)return 0;
int result = 1;//不为零,所有一定需要一个弓箭
sort(points.begin(), points.end());
for(int i = 1; i < points.size(); i++){
if(points[i][0] > points[i - 1][1]) result++;//i的左边界大于i-1的右边界,射箭
else points[i][1] = min(points[i][1],points[i - 1][1]);//i的左边界小于等于i-1的右边界,同时更新i的右边界为最小的右边界
}
return result;
}
};