贪心算法设计与例题

1.柠檬水找零

860. 柠檬水找零 - 力扣(LeetCode)

class Solution 
{
public:
    bool lemonadeChange(vector<int>& bills) 
    {
        int five=0,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)  //贪心:先把10块的找出去,留着5块的
                {
                    ten--;
                    five--;
                }
                else if(ten==0 && five>=3)
                {
                    five -= 3;
                }
                else return false;
            }
        }
        return true;
    }
};

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

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

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

3.最大数

179. 最大数 - 力扣(LeetCode)

class Solution 
{
public:
    string largestNumber(vector<int>& nums) 
    {
        //优化:把所有数转化为字符串
        vector<string> strs;
        for(int x:nums) strs.push_back(to_string(x));

        //自己的排序方法
        sort(strs.begin(),strs.end(),[](const string& s1,const string s2)
        {
            return s1+s2 > s2+s1;   //若s1+s2 > s2+s1,说明s1要排在s2前面
        });

        //提取结果
        string ret;
        for(auto& s:strs) ret += s;

        //处理前导0
        if(ret[0]=='0') return "0";
        return ret;
    }
};

4.摆动序列

376. 摆动序列 - 力扣(LeetCode)

class Solution 
{
public:
    int wiggleMaxLength(vector<int>& nums) 
    {
        int n=nums.size();
        if(n<=1) return n;

        int ret=0,left=0;
        for(int i=0;i<n-1;i++)
        {
            int right=nums[i+1]-nums[i];
            if(right==0) continue;
            if(right * left <= 0) ret++;
            left=right;
        }
        return ret+1;
    }
};

5.最长连续递增序列

674. 最长连续递增序列 - 力扣(LeetCode)

class Solution 
{
public:
    int findLengthOfLCIS(vector<int>& nums) 
    {
        int len=1;
        int left=0;
        int right=0;
        for(left=0,right=0;right<nums.size()-1;)
        {
            if(nums[right] < nums[right+1])
            {
                right++;
                len=max(len,right-left+1);
            }
            else
            {
                right++;
                left=right;
            }
        }
        return len;
    }
};

6.买卖股票的最佳时机

121. 买卖股票的最佳时机 - 力扣(LeetCode)

class Solution 
{
public:
    int maxProfit(vector<int>& prices) 
    {
        int ret=0;
        int prevmin=INT_MAX;
        for(int i=0;i<prices.size();i++)
        {
            ret=max(ret,prices[i]-prevmin);
            prevmin=min(prevmin,prices[i]);
        }
        return ret;
    }
};

7.买卖股票的最佳时机II

122. 买卖股票的最佳时机 II - 力扣(LeetCode)

class Solution 
{
public:
    int maxProfit(vector<int>& prices) 
    {
        int ret=0;
        int left=0,right=0;
        for(left=0,right=0;right<prices.size()-1;)
        {
            if(prices[right] < prices[right+1])
            {
                right++;
            }
            else
            {
                right++;
                left=right;
            }
            ret += prices[right]-prices[left];
            left=right;
        }
        return ret;
    }
};

8.按身高排序

2418. 按身高排序 - 力扣(LeetCode)

class Solution 
{
public:
    vector<string> sortPeople(vector<string>& names, vector<int>& heights) 
    {
        int n=names.size();
        vector<int> index(n);
        for(int i=0;i<n;i++) index[i]=i;  //下标数组

        sort(index.begin(),index.end(),[&](int i,int j)   //作为数组下标要加&
        {
            return heights[i] > heights[j];   //降序用大于
        });

        vector<string> ret;
        for(int i=0;i<n;i++)
        {
            ret.push_back(names[index[i]]);
        }
        return ret;
    }
};

9.优势洗牌(田忌赛马)

870. 优势洗牌 - 力扣(LeetCode)

class Solution 
{
public:
    vector<int> advantageCount(vector<int>& nums1, vector<int>& nums2) 
    {
        int n=nums1.size();
        //1.排序
        sort(nums1.begin(),nums1.end());
        vector<int> index2(n);
        for(int i=0;i<n;i++) index2[i]=i;
        sort(index2.begin(),index2.end(),[&](int i,int j)  //先根据nums2的大小关系排index
        {
            return nums2[i] < nums2[j];   //排升序
        });

        //2.田忌赛马
        vector<int> ret(n);
        int left=0,right=n-1;
        for(auto x:nums1)
        {
            if(x > nums2[index2[left]])
            {
                ret[index2[left]] = x;
                left++;
            }
            else
            {
                ret[index2[right]] = x;  //放在对面最大的位置上
                right--;
            }
        }
        return ret;
    }
};

10.增减字符串匹配

942. 增减字符串匹配 - 力扣(LeetCode)

class Solution 
{
public:
    vector<int> diStringMatch(string s) 
    {
        int n=s.size();
        vector<int> nums(n+1);
        vector<int> ret;
        for(int i=0;i<=n;i++) nums[i]=i;
        int left=0,right=n;

        for(auto ch:s)
        {
            if(ch=='I') 
            {
                ret.push_back(nums[left]);
                left++;
            }
            else
            {
                ret.push_back(nums[right]);
                right--;
            }
        }
        ret.push_back(nums[left]);
        return ret;
    }
};

11.分发饼干

455. 分发饼干 - 力扣(LeetCode)

class Solution
{
public:
    int findContentChildren(vector<int>& g, vector<int>& s) 
    {
        sort(g.begin(),g.end());
        sort(s.begin(),s.end());
        int count=0,i=0,j=0;
        while(j != s.size())
        {
            if(g[i] <= s[j]) 
            {
                count++;
                i++;
            }
            j++;

            if(count == g.size()) return count;
        }
        return count;
    }
};

12.最优除法

553. 最优除法 - 力扣(LeetCode)

class Solution 
{
public:
    string optimalDivision(vector<int>& nums) 
    {
        string ret;
        string tmp="(";
        int n=nums.size();
        if(n==1) 
        {
            ret=to_string(nums[0]);
        }
        else if(n==2)
        {
            string s1=to_string(nums[0]);
            string s2=to_string(nums[1]);
            ret = s1 + "/" + s2;
        }
        else
        {
            string s0=to_string(nums[0]);
            for(int i=1;i<n;i++)
            {
                tmp += to_string(nums[i]);
                if(i != n-1)
                {
                    tmp += "/";
                }
            }
            tmp += ")";
            ret = s0 + "/" + tmp;
        }
        return ret;
    }
};

13.跳跃游戏II

45. 跳跃游戏 II - 力扣(LeetCode)

class Solution 
{
public:
    int jump(vector<int>& nums) 
    {
        if(nums.size()==1) return 0;
        int left=0,right=0,ret=0,maxpos=0;
        int n=nums.size();
        while(maxpos < n)
        {
            if(maxpos==n-1) break;
            maxpos=0;
            for(int i=left;i<=right;i++)
            {
                maxpos=max(maxpos,i+nums[i]);
            }
            left=right+1;
            right=maxpos;
            ret++;
        }
        return ret;
    }
};

15.加油站

134. 加油站 - 力扣(LeetCode)

class Solution 
{
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) 
    {
        int n=gas.size();
        for(int i=0;i<n;i++)
        {
            int rest=0;
            int step=0;
            for(;step<n;step++)
            {
                int index=(i+step)%n;  //走step步之后的下标
                rest = rest+gas[index]-cost[index];
                if(rest < 0) break;
            }
            if(rest >= 0) return i;
            i = i + step;
        }
        return -1;
    }
};

16.单调递增的数字

738. 单调递增的数字 - 力扣(LeetCode)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
贪心算法在背包问题中的应用是一种常见的方法。背包问题是一个经典的优化问题,目标是在给定的背包容量下,选择一些物品放入背包,使得放入背包的物品总价值最大。 一个简单的贪心算法背包问题例题可以按照以下步骤进行解决: 1. 将所有物品按照单位重量的价值从大到小进行排序。 2. 初始化背包的容量为C,当前背包中放入的物品总价值为0。 3. 从价值最高的物品开始,依次尝试将物品放入背包。 - 如果当前物品的重量小于等于剩余背包容量,则放入背包,并更新当前背包中物品总价值和剩余背包容量。 - 如果当前物品的重量大于剩余背包容量,则不能放入背包,继续尝试下一个物品。 4. 重复步骤3,直到所有物品都被尝试过或者背包容量为0为止。 通过这个贪心算法,可以得到一个近似最优解,即放入背包的物品总价值最大化。但是需要注意的是,这个贪心算法并不能保证一定得到最优解,因为它只考虑了当前的最优选择,并没有全局地考虑所有可能的选择。 这个例题中的贪心算法背包问题可以帮助刚接触贪心算法的小白理解贪心算法的思想和应用。它通过按照单位重量的价值排序,优先选择单位重量价值最高的物品放入背包,从而达到最大化背包中物品总价值的目的。 <span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Greedy Algorithm - 副本 (2).zip](https://download.csdn.net/download/weixin_43817994/12262352)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [贪心算法--背包问题](https://blog.csdn.net/attack_5/article/details/84111786)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [【贪心算法】背包问题](https://blog.csdn.net/cqn2bd2b/article/details/128113815)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

对玛导至昏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值