算法训练营DAY29 第八章 贪心算法 part02
134. 加油站
134. 加油站 - 力扣(LeetCode)
思路
如果总消耗大于总油量,那肯定无法完成绕圈
令rest=gas-cost;循环中累加这个rest记为curSUM;如果curSum出现负数,让start记为i+1;curSum归零,重新计数;
遍历完后如果能完成绕圈,start记录的就是答案起始位置。
class Solution {
public:int curSum=0;int totalSum=0;int start=0;int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {for(int i=0;i<gas.size();i++){curSum+=(gas[i]-cost[i]);totalSum+=(gas[i]-cost[i]);if(curSum<0){start=i+1;curSum=0;}}if(totalSum<0)return -1;return start;}
};
135. 分发糖果
135. 分发糖果 - 力扣(LeetCode)
每个人都先给一个糖;然后从前往后遍历,如果右边的rating高就让右边的糖果数量等于左边糖果数量+1;再从后往前遍历,如果左边的rating高就让左边的糖果数量取max(当前左边的数量,右边的数量加1);
最后遍历一遍res求和。
class Solution {
public:int candy(vector<int>& ratings) {vector<int> res(ratings.size(),1);for(int i=0;i<ratings.size()-1;i++){if(ratings[i+1]>ratings[i]){res[i+1]=res[i]+1;}}for(int j=ratings.size()-1;j>0;j--){if(ratings[j-1]>ratings[j]){res[j-1]=max(res[j]+1,res[j-1]);}}int sum=0;for(int k=0;k<res.size();k++)sum+=res[k];return sum;}
};
860.柠檬水找零
860. 柠檬水找零 - 力扣(LeetCode)
贪心的点在于优先使用10+5给20找零,5+5+5次之;当找零不足的时候return false;其余就继续,最后循环外return true
class Solution {
public:bool lemonadeChange(vector<int>& bills) {int five=0,ten=0,twenty=0;for(int bill:bills){if(bill==5)five++;if(bill==10){if(five==0)return false;ten++;five--;}if(bill==20){if(ten>0&&five>0){ten--;five--;twenty++;}else if(ten==0&&five>=3){five-=3;twenty++;}else return false;}}return true;}
};
406.根据身高重建队列
406. 根据身高重建队列 - 力扣(LeetCode)
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>> que;for(int i=0;i<people.size();i++){int position=people[i][1];//1即意味着position=每一个人的k元素que.insert(que.begin()+position,people[i]);}return que;}
};
按照身高排序之后,优先按身高高的people的k来插入,后序插入节点也不会影响前面已经插入的节点,最终按照k的规则完成了队列。
所以在按照身高从大到小排序后:
局部最优:优先按身高高的people的k来插入。插入操作过后的people满足队列属性
全局最优:最后都做完插入操作,整个队列满足题目队列属性