【c++刷题笔记-贪心】day28: 134. 加油站 、 135. 分发糖果 、860.柠檬水找零 、 406.根据身高重建队列

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;
    }
};

总结

贪心就是以局部推全局并且没有反例的情况,当遇到不同维度的贪心时,需要分开讨论

相关推荐
-To be number.wan5 小时前
C++ 赋值运算符重载:深拷贝 vs 浅拷贝的生死线!
前端·c++
YGGP5 小时前
【Golang】LeetCode 64. 最小路径和
算法·leetcode
TheSumSt6 小时前
Python丨课程笔记Part3:语法进阶部分(控制结构与基础数据结构)
数据结构·笔记·python
古城小栈6 小时前
Rust变量设计核心:默认不可变与mut显式可变的深层逻辑
算法·rust
电商API&Tina7 小时前
跨境电商 API 对接指南:亚马逊 + 速卖通接口调用全流程
大数据·服务器·数据库·python·算法·json·图搜索算法
IT19957 小时前
Qt笔记-使用SSH2进行远程连接linux服务器并上传文件
linux·服务器·笔记
XXYBMOOO7 小时前
内核驱动开发与用户级驱动开发:深度对比与应用场景解析
linux·c++·驱动开发·嵌入式硬件·fpga开发·硬件工程
LYFlied7 小时前
【每日算法】LeetCode 1143. 最长公共子序列
前端·算法·leetcode·职场和发展·动态规划
长安er8 小时前
LeetCode 20/155/394/739/84/42/单调栈核心原理与经典题型全解析
数据结构·算法·leetcode·动态规划·
利刃大大8 小时前
【2025年度创作总结】从笔记到实践,从思考到生活融合
笔记·生活