贪心算法专题(Part1)

目录

[1. 贪心算法简介](#1. 贪心算法简介)

[2. 柠檬水找零](#2. 柠檬水找零)

[3. 将数组和减半的最少操作次数](#3. 将数组和减半的最少操作次数)

[4. 递增的三元子序列](#4. 递增的三元子序列)

[5. K次取反后最大化的数组和](#5. K次取反后最大化的数组和)

[6. 增减字符串匹配](#6. 增减字符串匹配)

[7. 分发饼干](#7. 分发饼干)

[8. 整数替换](#8. 整数替换)


1. 贪心算法简介

2. 柠檬水找零

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

题目展示:

题目分析

贪心策略:

分情况讨论:

a. 遇到5 元钱,直接收下;

b. 遇到10 元钱,找零5 元钱之后,收下;

c. 遇到20 元钱:

i. 先尝试凑0 + 5 的组合;

ii. 如果凑不出来,拼凑5 + 5 + 5 的组合;

这里就体现了贪心的思想,优先选择最优的方案。

代码实现

cpp 复制代码
class Solution {
public:
    bool lemonadeChange(vector<int>& bills) 
    {
        int five=0;
        int ten=0;
        for(auto x:bills)
        {
            if(x==5)
            {
                five++;
            }
            else if(x==10)
            {
                if(five==0) return false;
                else
                {
                    five--;
                    ten++;
                }
            }
            else
            {
                //贪心
                if(ten&&five)
                {
                    five--;
                    ten--;
                }
                else if (five>=3)
                {
                    five-=3;
                }
                else
                {
                    return false;
                }
            }
        }
        return true;
    }
};

3. 将数组和减半的最少操作次数

题目链接2208. 将数组和减半的最少操作次数 - 力扣(LeetCode)

题目展示

题目分析

贪心策略:

a. 每次挑选出「当前」数组中「最⼤」的数,然后「减半」;

b. 直到数组和减少到⾄少⼀半为止。 为了「快速」挑选出数组中最大的数,我们可以利用大根堆来寻找。

代码实现

cpp 复制代码
class Solution {
public:
    int halveArray(vector<int>& nums) 
    {
        priority_queue<double> heap;
        double sum=0;
        for(auto x:nums)
        {
            heap.push(x);
            sum+=x;
        }
        sum/=2.0;
        int count=0;
        while(sum>0)
        {
            double ret=heap.top()/2.0;
            heap.pop();
            sum-=ret;
            count++;
            heap.push(ret);         
        }
        return count;
    }
};

4. 递增的三元子序列

题目链接334. 递增的三元子序列 - 力扣(LeetCode)

题目展示

题目分析:

代码实现:

cpp 复制代码
class Solution {
public:
    bool increasingTriplet(vector<int>& nums) 
    {
        int a=nums[0];
        int b=INT_MAX;
        for(int i=0;i<nums.size();i++)
        {
            if(nums[i]>b) return true;
            else if(nums[i]>a) b=nums[i];
            else a=nums[i];
        }
        return false;
    }
};

5. K次取反后最大化的数组和

题目链接:1005. K 次取反后最大化的数组和 - 力扣(LeetCode)

题目展示;

题目分析:

代码实现:

cpp 复制代码
class Solution {
public:
    int largestSumAfterKNegations(vector<int>& nums, int k) 
    {
        int m=0;
        int n=nums.size();
        int minElem=INT_MAX;
        for(auto x:nums)
        {
            if(x<0)
            {
                m++;
            }
            minElem=min(minElem,abs(x));
        }
        int ret=0;
        if(m>k)
        {
            sort(nums.begin(),nums.end());
            for(int i=0;i<k;i++)
            {
                ret+=-nums[i];
            }
            for(int i=k;i<n;i++)
            {
                ret+=nums[i];
            }
        }
        else
        {
            //先把所有负数变成正数
            for(auto x:nums) ret+=abs(x);
            if((k-m)%2)
            {
                ret-=minElem*2;
            }
        }
        return ret;
    }
};

6. 增减字符串匹配

题目链接:942. 增减字符串匹配 - 力扣(LeetCode)

题目展示:

题目分析:

代码实现:

cpp 复制代码
class Solution {
public:
    vector<int> diStringMatch(string s) 
    {
        int left=0,right=s.size();
        vector<int> ret;
        for(auto ch:s)
        {
            if(ch=='I')
            {
                ret.push_back(left++);
            }
            else if(ch=='D')
            {
                ret.push_back(right--);
            }
        }
        ret.push_back(left);
        return ret;
    }
};

7. 分发饼干

题目链接:455. 分发饼干 - 力扣(LeetCode)

题目展示:

题目分析:

代码实现:

cpp 复制代码
class Solution {
public:
    int findContentChildren(vector<int>& g, vector<int>& s) 
    {
        int ret=0;
        int m=g.size();
        int n=s.size();
        //排序
        sort(g.begin(),g.end());
        sort(s.begin(),s.end());
        for(int i=0,j=0;i<m&&j<n;i++,j++)
        {
            while(j<n&&s[j]<g[i]) j++;
            if(j<n) ret++;
        }
        return ret;
    }
};

8. 整数替换

题目链接:397. 整数替换 - 力扣(LeetCode)

题目展示:

题目分析:

代码实现:

相关推荐
青草地溪水旁13 小时前
C++中的Reactor和Proactor模型进行系统性解析
c++·网络编程‘
AMiner:AI科研助手13 小时前
警惕!你和ChatGPT的对话,可能正在制造分布式妄想
人工智能·分布式·算法·chatgpt·deepseek
深耕AI16 小时前
【MFC中OnInitDialog虚函数详解:哪个是虚函数?两个OnInitDialog的关系】
c++·mfc
CHANG_THE_WORLD16 小时前
并发编程指南 同步操作与强制排序
开发语言·c++·算法
pl002016 小时前
C++虚函数&虚析构函数&纯虚函数的使用说明和理解
c++·虚函数·纯虚函数·虚析构函数
gaoshou4517 小时前
代码随想录训练营第三十一天|LeetCode56.合并区间、LeetCode738.单调递增的数字
数据结构·算法
自信的小螺丝钉17 小时前
Leetcode 240. 搜索二维矩阵 II 矩阵 / 二分
算法·leetcode·矩阵
KING BOB!!!19 小时前
Leetcode高频 SQL 50 题(基础版)题目记录
sql·mysql·算法·leetcode
小wanga19 小时前
C++知识
java·开发语言·c++
深思慎考19 小时前
LinuxC++项目开发日志——高并发内存池(1-定长内存池)
linux·c++