贪心算法精品题

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;
    }
};
相关推荐
PAK向日葵1 小时前
【算法导论】PDD 0817笔试题题解
算法·面试
地平线开发者4 小时前
ReID/OSNet 算法模型量化转换实践
算法·自动驾驶
地平线开发者4 小时前
开发者说|EmbodiedGen:为具身智能打造可交互3D世界生成引擎
算法·自动驾驶
星星火柴9365 小时前
关于“双指针法“的总结
数据结构·c++·笔记·学习·算法
艾莉丝努力练剑6 小时前
【洛谷刷题】用C语言和C++做一些入门题,练习洛谷IDE模式:分支机构(一)
c语言·开发语言·数据结构·c++·学习·算法
C++、Java和Python的菜鸟7 小时前
第六章 统计初步
算法·机器学习·概率论
Cx330❀7 小时前
【数据结构初阶】--排序(五):计数排序,排序算法复杂度对比和稳定性分析
c语言·数据结构·经验分享·笔记·算法·排序算法
散1127 小时前
01数据结构-Prim算法
数据结构·算法·图论
起个昵称吧8 小时前
线程相关编程、线程间通信、互斥锁
linux·算法
myzzb8 小时前
基于uiautomation的自动化流程RPA开源开发演示
运维·python·学习·算法·自动化·rpa