贪心算法精品题

1.找钱问题

本题的贪心策略在于我们希望就可能的保留作用大的5元

cpp 复制代码
class Solution {
public:
    bool lemonadeChange(vector<int>& bills) {
        std::map<int ,int> _map;
        for(auto ch:bills)
        {
            if(ch == 5) _map[ch]++;
            else if(ch == 10)
            {
                if(_map[5] == 0) return false;
                else{
                    _map[5]--;
                    _map[ch]++;
                }
            }
            else if(ch == 20){
                //这里的判断_map [5]!= 0 && _map[10] != 0其实是贪心我用10元代替两张5
                if(_map [5]!= 0 && _map[10] != 0)
                {
                    _map[5]--;_map[10]--;
                    _map[ch]++;
                }
                else if(_map[5] >= 3)
                {
                    _map[5] -= 3;
                    _map[ch]++;
                }
                else return false;
            }
        }
        return true;
    }
};

题目链接:860. 柠檬水找零 - 力扣(LeetCode)

2.最大数

这道题涉及一个知识点:一个数比另一个数大那么转换为字符串以后对应的大小关系并不会改变

那么对于 string A = "12" string B = "23" string C = "14".如果进行排序由于BA大于AB故B位于A的前面由于CA大于AC所以C位于A的前面 故顺序为:B C A那么BCA是不是他们组成的最大数呢这里显然是,但是要以此类推就能知道这题我们只需要重载排序规则就能完成,当然这题还存在一些便捷条件比如如个排序数组的开头是"0"说明这些数着的最大值就是0

cpp 复制代码
class Solution {
public:
    static bool compare(int a,int b)
    {
        std::string A = std::to_string(a);
        std::string B = std::to_string(b);
        std::string AB = A+B;
        std::string BA = B+A;
        return AB>BA;
    } 
    string largestNumber(vector<int>& nums) {
        sort(nums.begin(),nums.end(),compare);
        string ret;
        for(auto ch:nums) ret+=std::to_string(ch);
        return ret[0] == '0'?"0":ret;
    }
};

题目链接:179. 最大数 - 力扣(LeetCode)

3.摆动序列

这个题目可以理解为找到一个子序列,满足子序列内的元素时先增在减或者先减在增的,就类似正弦函数。

我们怎么才能找到最长的满足条件的子序列呢,我先做了一个我就找极大值和极小值来组成这个子序列,然后就过了,很神奇,然后看了看题解才明白为什么

看这张图,我们发现其实有三条可选择的路径但是其实本质上都是一样的,都是上升区间取一个值然后在相邻的下降区间取一个比自己小的数

那么我们的贪心策略就是直接去上升区间和下降区间的端点也就是极大值和极小值。

cpp 复制代码
class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        int left = 0,right = 0;int ret = 0;
        for(int i = 0;i<nums.size()-1;i++)
        {
            right = nums[i+1]-nums[i];
            if(right == 0) continue;
            else if(right*left<=0)
            {
                left = right;
                ret++;
            }
            else continue;
        }
        return ret+1;
    }
};
相关推荐
Freshman小白11 分钟前
python算法打包为docker镜像(边缘端api服务)
python·算法·docker
mit6.82432 分钟前
[VT-Refine] Simulation | Fine-Tuning | docker/run.sh
算法
朴shu37 分钟前
Delta数据结构:深入剖析高效数据同步的奥秘
javascript·算法·架构
mit6.8241 小时前
博弈dp|凸包|math分类
算法
Shinom1ya_1 小时前
算法 day 41
数据结构·算法·leetcode
hetao17338372 小时前
2025-10-30 ZYZOJ Star(斯达)模拟赛 hetao1733837的record
c++·算法
无敌最俊朗@2 小时前
C++ 值类别与移动语义详解(精简版)
java·数据结构·算法
lingran__3 小时前
算法沉淀第十一天(序列异或)
c++·算法
一匹电信狗3 小时前
【C++】红黑树详解(2w字详解)
服务器·c++·算法·leetcode·小程序·stl·visual studio
寂静山林3 小时前
UVa 11853 Paintball
算法