代码随想录刷题03.15
贪心算法4
LeetCode题目
解题思路
1.本题中的贪心思路:
局部最优:遇到账单20,优先消耗美元10,完成本次找零。全局最优:完成全部账单的找零。代码随想录的思路更加清晰。
if (bills == 20) {
// 优先消耗10美元,因为5美元的找零用处更大,能多留着就多留着
if (five > 0 && ten > 0) {
five–;
ten–;
} else if (five >= 3) {
five -= 3;
} else return false;
}
2.遇到感觉没有思路的题目,可以静下心来把能遇到的情况分析一下,只要分析到具体情况了,一下子就豁然开朗了。
代码过程
class Solution {
public:
int n1=0,n2=0;
bool lemonadeChange(vector<int>& bills) {
for(int i=0;i<bills.size();i++)
{
if(bills[i]==5)n1++;
if(bills[i]==10){
if(n1==0)return false;
else{
n1--;
n2++;
}
}
if(bills[i]==20){
if((n1==0&&n2!=0)||(n1<=2&&n2==0))return false;
if(n1!=0&&n2!=0){
n1--;
n2--;
continue;
}
if(n1>=3)n1-=3;
}
}
return true;
}
};
LeetCode题目
解题思路
1.遇到两个维度权衡的时候,一定要先确定一个维度,再确定另一个维度:即先以一个标准(方向)进行遍历,再以另一个标准(方向)进行遍历;
2.本题思路:先以身高进行遍历排序,再以前面高的人的个数进行第二轮遍历。
注意:在第二轮重新排序的时候为了避免后面的数把前面的数覆盖掉,使用insert操作,而不是用下标索引进行操作。
代码过程
class Solution {
public:
static bool cmp(vector<int>& a,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) {
vector<vector<int>>que;
sort(people.begin(),people.end(),cmp);
for(int i=0;i<people.size();i++)
{
que.insert(que.begin()+people[i][1],people[i]);
}
return que;
}
};
LeetCode题目
解题思路
1.重复的题目要分出有重复和不重复的情况;
2.在数据结构示意图上要清楚分辨出各个变量(指针)是如何移动的。
3.从贪心的角度来说,本题依然只是单次遍历:
局部最优:当气球出现重叠,一起射,所用弓箭最少。全局最优:把所有气球射爆所用弓箭最少。
代码过程
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;
sort(points.begin(),points.end(),cmp);
int result=1;
for(int i=1;i<points.size();i++)
{
if(points[i-1][1]<points[i][0])result++;
else{
points[i][1]=min(points[i-1][1],points[i][1]);
}
}
return result;
}
};