贪心算法精品题

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;
    }
};
相关推荐
爱喝矿泉水的猛男2 小时前
非定长滑动窗口(持续更新)
算法·leetcode·职场和发展
YuTaoShao2 小时前
【LeetCode 热题 100】131. 分割回文串——回溯
java·算法·leetcode·深度优先
YouQian7722 小时前
Traffic Lights set的使用
算法
go54631584654 小时前
基于深度学习的食管癌右喉返神经旁淋巴结预测系统研究
图像处理·人工智能·深度学习·神经网络·算法
aramae4 小时前
大话数据结构之<队列>
c语言·开发语言·数据结构·算法
大锦终4 小时前
【算法】前缀和经典例题
算法·leetcode
想变成树袋熊4 小时前
【自用】NLP算法面经(6)
人工智能·算法·自然语言处理
cccc来财5 小时前
Java实现大根堆与小根堆详解
数据结构·算法·leetcode
Coovally AI模型快速验证6 小时前
数据集分享 | 智慧农业实战数据集精选
人工智能·算法·目标检测·机器学习·计算机视觉·目标跟踪·无人机
墨尘游子6 小时前
目标导向的强化学习:问题定义与 HER 算法详解—强化学习(19)
人工智能·python·算法