【贪心算法】:LeetCode860.柠檬水找零

朋友们、伙计们,我们又见面了,本专栏是关于各种算法的解析,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成!

C 语 言 专 栏:C语言:从入门到精通

数据结构专栏:数据结构

个  人  主  页 :stackY、

C + + 专 栏   :C++

Linux 专 栏  :Linux

目录

1. 题目解析

2. 算法原理讲解

3. 代码实现

4. 贪心策略证明


1. 题目解析

LeetCode860.柠檬水找零:https://leetcode.cn/problems/lemonade-change/description/icon-default.png?t=N7T8https://leetcode.cn/problems/lemonade-change/description/

860. 柠檬水找零

在柠檬水摊上,每一杯柠檬水的售价为 5 美元。顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。

每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5 美元。

注意,一开始你手头没有任何零钱。

给你一个整数数组 bills ,其中 bills[i] 是第 i 位顾客付的账。如果你能给每位顾客正确找零,返回 true ,否则返回 false 。

示例 1:

输入:bills = [5,5,5,10,20]
输出:true
解释:
前 3 位顾客那里,我们按顺序收取 3 张 5 美元的钞票。
第 4 位顾客那里,我们收取一张 10 美元的钞票,并返还 5 美元。
第 5 位顾客那里,我们找还一张 10 美元的钞票和一张 5 美元的钞票。
由于所有客户都得到了正确的找零,所以我们输出 true。

示例 2:

输入:bills = [5,5,10,10,20]
输出:false
解释:
前 2 位顾客那里,我们按顺序收取 2 张 5 美元的钞票。
对于接下来的 2 位顾客,我们收取一张 10 美元的钞票,然后返还 5 美元。
对于最后一位顾客,我们无法退回 15 美元,因为我们现在只有两张 10 美元的钞票。
由于不是每位顾客都得到了正确的找零,所以答案是 false。

提示:

  • 1 <= bills.length <= 105
  • bills[i] 不是 5 就是 10 或是 20 

根据题意:首先找零是按照顺序来进行的,不能“插队”,并且刚开始我们身无分文。

假设第一个顾客给5块,那么直接收下即可;

如果第一个顾客给的不是5块,那表示需要给顾客找零,但是此时我们没有钱,所以直接返回false即可。 

2. 算法原理讲解

首先:我们根据顾客支付的钱可以分为三种情况:

1. 顾客支付5元 -> 直接收下即可;

2. 顾客支付10元 -> 直接收下,并且判断身上是否有5元,如果有找零给顾客,如果没有直接返回false;

3. 顾客支付20元 -> 直接收下,此时给顾客找零就存在两种方法:

        ① 找给顾客一张10元和一张5元;

        ② 找给顾客三张5元;

那么该如何选择上述两种情况呢?

就需要用到贪心算法,那么到底该怎么贪才是最优呢?

上面的两种方法其本质上就是一张10元与两张5元的区别,那么根据贪心策略该怎么贪呢?

仔细观察不难发现,5元的用处是很大的,不仅可以给10元找零,还可以给20元找零,那么既然5元用处这么大,就表示5元比较珍贵,所以越珍贵的东西我们越舍不得用,所以尽量选择找零5元比较少的那一个方法,所以我们的贪心策略是:尽可能少的使用5元钱给顾客找零。

3. 代码实现

怎么记录我们手上的钱呢?

可以使用两个变量来统计此时我们手中所具有的5元钱的张数(cnt_five)和10元钱cnt_ten),然后遍历bills,遇到5元将cnt_five++,遇到10元钱先看自己手里有没有钱,遇到20元首先考虑的就是10+5的策略,再考虑5+5+5的策略。

class Solution 
{
public:
    bool lemonadeChange(vector<int>& bills) 
    {
        //统计5元钱和10元钱的张数
        int cnt_ten = 0, cnt_five = 0; 
        //遍历
        for(auto& e : bills)
        {
            if(e == 5) cnt_five++;   //遇到5元就收下
            else if(e == 10)         //遇到10元
            {
                cnt_ten++;
                if(cnt_five) cnt_five--; //先判断是否可以找零
                else return false;
            }
            else                     //遇到20元
            {
                if(cnt_five && cnt_ten) //先考虑10+5的策略
                {
                    cnt_five--;
                    cnt_ten--;
                }
                else if(cnt_five >= 3) cnt_five -= 3; //再考虑5+5+5的策略
                else return false;
            }
        }
        //走到这里就说明找零成功
        return true;
    }
};

4. 贪心策略证明

那么如果证明我们选择的这种贪心策略是否正确呢?

需要用到:交换论证法

例如:

假设贪心解为 [a, b, c, d, e, f]

假设最优解为 [e, b, c, d, a, f]

交换论证就是在不破坏最优解的“最优性质”的前提下可以通过一定的调整将最优解转化为贪心解即可

将最优解里面的e和a交换,这样既没有破坏最优解性质,同样也可以将最优解转化为贪心解,则表示该贪心策略正确。

在本题中使用交换论证法:遇到顾客给20元,贪心解是用10元和5元进行找零,最优解是用三张5元进行找零,区别就在于两张5元和一张10元。

顾客         ...  5   10   20        10  ...

贪心解     ...  0    5   10+5      5  ...

最优解     ...  0    5    5+5+5   5  ...

那么在整个找零过程中,最优解的10元存在花与不花两种情况:

① 如果在前面或者后面的找零过程中,将10元钱花了,那么在后面花的10元钱可以将这里的5+5给替换掉,此时也就变成了贪心解;

② 如果在前面或者后面的找零过程中,没有将10钱花掉,那么就可以用没花掉的10元钱替换掉这里的5+5,此时也变成了贪心解。

所以通过交换论证法证明了最优解可以在不改变最优条件的性质下变成贪心解,所以证明我们的贪心策略(选择花费5元较少的一种方法)是正确的。

朋友们、伙计们,美好的时光总是短暂的,我们本期的的分享就到此结束,欲知后事如何,请听下回分解~,最后看完别忘了留下你们弥足珍贵的三连喔,感谢大家的支持!      

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/409515.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu22.04和Windows10双系统安装

概要 本篇演示Ubuntu22.04和Windows10双系统的安装。先安装Ubuntu22.04&#xff0c;再安装Windows10。 一、说明 1、电脑 笔者的电脑品牌是acer(宏碁/宏基) 电脑开机按F2进入BIOS 电脑开机按F12进入Boot Manager 2、U盘启动盘 需要用到两个U盘启动盘 &#xff08;1&a…

kubernetes集群搭建(1.26版本)

集群搭建 1.初始化安装k8s集群的实验1.1修改主机名称1.2关闭防火墙1.3关闭SELINUX1.4配置主机hosts文件&#xff0c;相互之间通过主机名访问1.5配置主机之间无密码登录1.6关闭交换分区swap&#xff0c;提升性能1.7修改机器内核参数1.9配置阿里云的repo源1.10配置安装k8s组件需要…

力扣● 343. 整数拆分 ● 96.不同的二叉搜索树

● 343. 整数拆分 想不到&#xff0c;要勇于看题解。 关键在于理解递推公式。 1、DP数组及其下标的含义&#xff1a;dp[i]是分解i这个数得到的最大的乘积。 2、DP数组如何初始化&#xff1a;dp[0]和dp[1]都没意义&#xff0c;所以直接不赋值&#xff0c;初始化dp[2]1即可。…

让程序员设计B端界面,好比武大郎招聘:向我看齐。不忍直视!

hello&#xff0c;我是大美B端工场&#xff0c;B端系统的要求越来越高了&#xff0c;很多公司还让程序员负责页面&#xff0c;页面搞的没法看&#xff0c;也怪不得程序员。程序员来搞页面&#xff0c;那还不是武大郎招聘——向我看齐&#xff0c;以我的标准为标准吗&#xff1f…

python 基础知识点(蓝桥杯python科目个人复习计划49)

今日复习内容&#xff1a;做复习题 例题1&#xff1a;希尔排序 题目描述&#xff1a; 希尔排序是直接插入排序算法的一种更高效的改进版本&#xff0c;但它是非稳定排序算法。希尔排序是基于插入排序的以下两点性质而提出的改进方法之一&#xff1a; 1.插入排序在对几乎已经…

预训练-微调范式在人工智能领域的深远影响

预训练-微调范式的出现是人工智能领域的一大里程碑&#xff0c;它深刻改变了深度学习模型的训练方式和应用模式&#xff0c;并对整个行业产生了多方面的深远影响&#xff1a; 数据效率提升&#xff1a; 通过在大规模无标注数据上进行预训练&#xff0c;模型能够学习到丰富的语言…

linux常用的网络命令实战分享

文章目录 ifup/down命令ifconfig命令观察网络接口信息修改接口参数增加虚拟网络接口 route命令查看路由表增加路由表规则删除路由表规则 IP 命令ip linkip addr设定路由 ip route arp 命令 在实际研发运维工作中常常会涉及到网关相关的操作和知识&#xff0c;这里对linux下常用…

(详细使用指南)Linux下交叉编译带ffmpeg的opencv并移植到RK3588等ARM端

一 问题背景 瑞芯微RK3588等嵌入式板作为边缘端设备为算法模型的部署提供了便利&#xff0c;目前很多分类或好检测模型针对边缘端做了优化或量化&#xff0c;使得在边缘端也能达到实时稳定的识别和检测效果。 但嵌入式设备普遍的flash emmc不大&#xff0c;一般在32G左…

【数据结构与算法】(20)高级数据结构与算法设计之 Greedy Algorithm 贪心算法 代码示例与详细讲解

目录 4.2 Greedy Algorithm1) 贪心例子DijkstraPrimKruskal 2) 零钱兑换问题有几个解&#xff08;零钱兑换 II&#xff09;Leetcode 518最优解&#xff08;零钱兑换&#xff09;- 穷举法 Leetcode 322最优解&#xff08;零钱兑换&#xff09;- 贪心法 Leetcode 322 3) Huffman …

9.5K Star,又一款超棒开源轻量自动化运维平台

Hi&#xff0c;骚年&#xff0c;我是大 G&#xff0c;公众号「GitHub指北」会推荐 GitHub 上有趣有用的项目&#xff0c;一分钟 get 一个优秀的开源项目&#xff0c;挖掘开源的价值&#xff0c;欢迎关注。 一个好的运维平台就变得非常重要了&#xff0c;可以节省大量的人力和物…

【HarmonyOS】低代码开发—使用低代码开发服务卡片

DevEco Studio还支持使用低代码开发功能开发服务卡片&#xff0c;目前只支持JS语言&#xff0c;且compileSdkVersion必须为7或以上。 下面以创建一个新的服务卡片为例进行说明。 1.打开一个工程&#xff0c;创建服务卡片&#xff0c;创建方法包括如下两种方式&#xff1a; 选…

SpringBoot自带的tomcat的最大连接数和最大的并发数

先说结果&#xff1a;springboot自带的tomcat的最大并发数是200&#xff0c; 最大连接数是&#xff1a;max-connectionsaccept-count的值 再说一下和连接数相关的几个配置&#xff1a; 以下都是默认值&#xff1a; server.tomcat.threads.min-spare10 server.tomcat.threa…

老隋蓝海项目temu跨境电商好不好做?

近年来&#xff0c;跨境电商成为我国对外贸易的新亮点&#xff0c;其中Temu作为拼多多旗下的新兴跨境电商平台&#xff0c;吸引了众多国内卖家参与。老隋作为行业内的知名人士&#xff0c;他对Temu跨境电商项目的评价备受关注。本文将分析老隋对Temu跨境电商的看法&#xff0c;…

RDMA内核态函数ib_post_send()源码分析

最近调用linux内核下RDMA的Verb API ib_post_send()出现了问题&#xff0c;因此从源码分析一下这个函数的调用过程。 我使用的内核版本为5.15.0-94 这是函数ib_post_send的头文件定义&#xff0c;这个函数的意义是向发送队列提交发送请求&#xff0c;他会调用qp对应设备的post_…

Pyglet综合应用|推箱子游戏地图编辑器之图片跟随鼠标

目录 推箱子游戏 升级一&#xff1a;鼠标操作 升级二&#xff1a;增加网格 升级三&#xff1a;模拟按钮 综合应用&#xff1a;地图编辑器 关卡地图洗数 推箱子游戏 本篇为之前写的博客《Pyglet综合应用&#xff5c;推箱子游戏之关卡图片载入内存》的续篇&#xff0c;内容…

项目:shell实现多级菜单脚本编写

目录 1. 提示 2. 演示效果 2.1. 一级菜单 2.2. 二级菜单 2.3. 执行操作 3. 参考代码 1. 提示 本脚本主要实现多级菜单效果&#xff0c;并没有安装LAMP、LNMP环境&#xff0c;如果要用在实际生成环境中部署LNMP、LAMP环境&#xff0c;只需要简单修改一下就可以了。 2. 演…

ASCII编码的影响与作用:数字化时代的不可或缺之物

title: ASCII编码的影响与作用&#xff1a;数字化时代的不可或缺之物 date: 2024/2/25 16:03:37 updated: 2024/2/25 16:03:37 tags: ASCII起源标准化字符文本处理基础编程语言基石数据库存储标准跨平台兼容多语言编码基础 一、ASCII编码的起源 ASCII&#xff08;American St…

matlab 三质量-弹簧系统受激振力

1、内容简介 略 44-可以交流、咨询、答疑 建立系统运动方程&#xff0c;研究固有频率和对应主振型 2、内容说明 略 三质量&#xff0d;弹簧系统受激振力&#xff0c;并不考虑各自的阻尼。建立系统运动方程。 解&#xff1a;由于阻尼对固有频率没有影响&#xff0c;故本文不…

浅谈数据分析工具在智慧城市中的作用

随着城市化、技术进步和人口不断增长&#xff0c;智慧城市已成为当今世界主要技术发展之一。 智慧城市设备依靠描述模型对城市环境产生的大量数据进行数据分析。 在这种城市景观中&#xff0c;智慧城市是技术和可持续的城市地区&#xff0c;利用信息和通信技术(ICT)来改善城市…

异步http和同步http原理和差异

开发服务器端程序时&#xff0c;一种常见的需求是&#xff0c;通过向另一个http服务器发送请求&#xff0c;获得数据。最常规的作法是使用同步http请求的方式&#xff0c;过程如下 这种方式简单好用&#xff0c;但是在高并发场景下有缺陷。在单线程环境下&#xff0c;程序发送h…