134. 加油站 - 力扣(LeetCode)
思路:算出当前的消耗的油量总数,如果花费大于油量表示无法到达。统计总花费最大的油耗总数,如果油耗总数大于或者等于0,表示全程没有负花销,直接从0起步。小于零就从后向前遍历,当总最大油耗抹平就返回当时的下标
重点:使用min记录从0开始的最大总油耗
cpp
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int n=gas.size();
int cur=0;
int min=INT_MAX;
for(int i=0;i<n;i++){
int t=gas[i]-cost[i];
cur+=t;
if(cur<min){
min=cur;
}
}
if(cur<0){
return -1;
}
if(min>=0){
return 0;
}
for(int i=n-1;i>=0;i--){
int t=gas[i]-cost[i];
min+=t;
if(min>=0){
return i;
}
}
return -1;
}
};
135. 分发糖果 - 力扣(LeetCode)
思路:从前向后遍历给右边评分比左边评分大的孩子分发一个糖果,从后向前遍历给左边比右边大孩子分发糖果,同时比较左边评分比右边评分高的孩子的糖果数和右边评分最高的糖果数,选最大值作为结果。
重点:左右两个方向分开考虑,先左再右
cpp
class Solution {
public:
int candy(vector<int>& ratings) {
int n=ratings.size();
vector<int>ans(n,1);
for(int i=1;i<n;i++){
if(ratings[i]>ratings[i-1]){
ans[i]=ans[i-1]+1;
}
}
for(int i=n-2;i>=0;i--){
if(ratings[i]>ratings[i+1]){
ans[i]=max(ans[i+1]+1,ans[i]);
}
}
int res=0;
for(int x:ans){
res+=x;
}
return res;
}
};
860. 柠檬水找零 - 力扣(LeetCode)
思路:记录5元钱的数量,当付的是10元时消耗1张5元。当付的是20元时如果有10元零钱,优先消耗一张10元和一张5元。没有就消耗三张5元。然后判断5元数量是否小于零,小于零表示无法完成找零
cpp
class Solution {
public:
bool lemonadeChange(vector<int>& bills) {
int five=0,ten=0;
for(int a:bills){
if(a==5){
five++;
}else if(a==10){
five--;
ten++;
}else if(ten){
ten--;
five--;
}else{
five-=3;
}
if(five<0){
return false;
}
}
return true;
}
};
406. 根据身高重建队列 - 力扣(LeetCode)
思路:先按照身高从到小排序,再按照前k个人从小到大排序。然后新建一个队列,从左到右按照前k个人插入到下标为k的地方
cpp
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++){
que.insert(que.begin()+people[i][1],people[i]);
}
return que;
}
};
总结
贪心就是以局部推全局并且没有反例的情况,当遇到不同维度的贪心时,需要分开讨论