双“11”搞促销?用贪心算法来盘他!

作者 | 王磊

来源 | Java中文社群(ID:javacn666)

转载请联系授权(微信ID:GG_Stone)

这几年商家为了刺激消费是变着花样的推出各种各样的活动,以某多多为首的运营式电商更是让我们看到了营销的无限“潜力”。

这不,最近刚赶上双 11,小区便利店的老王头也推出了一项「空酒瓶子换酒」的促销活动,它的规则是这样的。

本文已收录至 Github《小白学算法》系列:https://github.com/vipstone/algorithm

活动规则

客户购买 X 瓶酒,就可以用 Y 个空酒瓶来兑换一瓶新酒。

提示:

X 和 Y 的取值如下:

  • 1 <= X <= 100

  • 2 <= Y <= 100

Y 值不固定,随机抽取。

如果喝掉了酒瓶中的酒,那么酒瓶就会变成空的。

请你计算最多能喝到多少瓶酒

示例 1:

输入:X = 9, Y = 3

输出:13

解释:你可以用 3 个空酒瓶兑换 1 瓶酒。所以最多能喝到 9 + 3 + 1 = 13 瓶酒。

示例 2:

输入:X = 15, Y = 4

输出:19

解释:你可以用 4 个空酒瓶兑换 1 瓶酒。所以最多能喝到 15 + 3 + 1 = 19 瓶酒。

示例 3:

输入:X = 5, Y = 5

输出:6

示例 4:

输入:X = 2, Y = 3

输出:2

解题思路

这道题难点有两个:第一,用多少个空瓶换一瓶酒是不固定的(随机的);第二,兑换的酒喝完之后还能继续参与兑换活动。因此要在满足这两个的前提条件下,计算自己最多能喝到几瓶。

可能有些朋友看到了本篇标题之后就知道了解题思路,没错,我们本文就是要用「贪心算法」来计算最终答案。同时这道题也符合贪心算法的解题思路,那就是有酒瓶就兑换、能兑换多少就兑换多少。

贪心算法

贪心算法(Greedy Algorithm),又称贪婪算法,是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是最好或最优的算法。

贪心算法在有最优子结构的问题中尤为有效。最优子结构的意思是局部最优解能决定全局最优解。简单地说,问题能够分解成子问题来解决,子问题的最优解能递推到最终问题的最优解。

贪心算法的实现框架

从问题的初始解出发:

while(能朝给定总目标前进一步)

{

    利用可行的决策,求出一个可行解元素;

}

由所有解元素组合成问题的一个可行解。

注意:因为用贪心算法只能通过解局部最优解的策略来达到全局最优解,因此,一定要注意判断问题是否适合采用贪心算法策略,找到的解是否一定是问题的最优解。

接下来我们就用代码来演示一下贪心算法的具体实现。

代码实现 1:贪心

首先我们先把全局问题转换成局部问题:当空瓶子能换一瓶酒的时候,我们就换一瓶酒,实现代码如下:

// 贪心1:用 + 和 - 实现
class Solution {public int numWaterBottles(int numBottles, int numExchange) {// 最大酒瓶数int total = numBottles;// 有酒瓶就兑换while (numBottles >= numExchange) {// 执行一轮兑换numBottles -= numExchange;++total;// 兑换一次多一个酒瓶++numBottles;}return total;}
}

代码解析

实现思路:

  1. 先把所有酒喝掉 int total = numBottles

  2. 有足够的空瓶就去换一瓶酒,执行一次 while 循环;

  3. 在循环中,空瓶的数量 +1,能喝到酒的数量 +1;

  4. 执行下一次循环判断。

我们将以上代码提交至 LeetCode,执行结果如下:

代码实现 2:贪心改进

以上的贪心算法是一瓶酒一瓶酒进行循环兑换的,那我们可否每次将所有的空瓶子全部兑换完(可兑换的最大值),然后将兑换的酒再喝完,再进行下一次兑换?

答案是肯定的,我们只需要使用取模和取余操作就可以实现了,具体代码如下:

// 贪心 2:用 / 和 % 实现
class Solution {public int numWaterBottles(int numBottles, int numExchange) {// 总酒瓶数int total = numBottles;// 有酒瓶就兑换while (numBottles >= numExchange) {// 最多可兑换的新酒int n = numBottles / numExchange;// 累计酒瓶total += n;// 剩余酒瓶(剩余未兑换 + 已兑换喝掉的)numBottles = numBottles % numExchange + n;}return total;}
}

我们将以上代码提交至 LeetCode,执行结果如下:

总结

贪心算法初看感觉很“难”,但具体实现起来却发现很简单。其实「算法」也是一样的,初看这个词感觉很难很高大上,其实它就是解决某个问题的一种思想、一种固定的“套路”而已,也并无神秘可言。

人常说:路虽远行则将至,事虽然难做者必成。“难”和“易”从来都是相对的,其实从“难”到“易”就是一个逐渐开悟、逐渐成长的过程。

愿你每天成长一点,最后留一个我的私人微信:GG_Stone,相互交流、共同进步。

参考 & 鸣谢

https://leetcode-cn.com/problems/water-bottles/

https://www.cnblogs.com/steven_oyj/archive/2010/05/22/1741375.html

https://zh.wikipedia.org/zh-hans/贪心算法


往期推荐

嗯,查询滑动窗口最大值的这4种方法不错....


小白学算法:买卖股票的最佳时机!


23张图!万字详解「链表」,从小白到大佬!


关注我,每天陪你进步一点点!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AndroidStudio使用入门

AndroidStudio使用入门1_AndroidStudio activity的基本使用1.1_MainActivity和activity_main的初识1.2_Activity的清单文件简介1.3_几种重要文件的介绍1.4_基本布局的认识与使用1.4.1_RelativeLayout(相对布局)1.4.2_线性布局2_访问资源的方式2.1_java访问资源的方式2.2_xml访问…

面试官:你说说互斥锁、自旋锁、读写锁、悲观锁、乐观锁的应用场景?

前言生活中用到的锁&#xff0c;用途都比较简单粗暴&#xff0c;上锁基本是为了防止外人进来、电动车被偷等等。但生活中也不是没有 BUG 的&#xff0c;比如加锁的电动车在「广西 - 窃格瓦拉」面前&#xff0c;锁就是形同虚设&#xff0c;只要他愿意&#xff0c;他就可以轻轻松…

2万字,看完这篇才敢说自己真的懂线程池!

前言 线程池可以说是 Java 进阶必备的知识点了&#xff0c;也是面试中必备的考点&#xff0c;可能不少人看了一些文章后能对线程池工作原理说上一二&#xff0c;但这还远远不够&#xff0c;如果碰到比较有经验的面试官再继续追问&#xff0c;很可能会被吊打&#xff0c;考虑如下…

西南大学校园GIS平台

原文:西南大学校园GIS平台系统架构是B/S,开发语言是C#、silverlight&#xff0c;开发平台是.NET&#xff0c;数据库为sqlserver&#xff0c;这是我读研究生时候自己做的作品&#xff0c;以自己的母校为地图&#xff0c;进行GIS相关的功能分析&#xff0c;核心的模块有&#xff…

Android studio小问题解决

1_代码识别不出来问题 2_项目SDK与本地不匹配 先查看项目的SDK 增加本地SDK

2万字长文包教包会 JVM 内存结构

点击蓝色“Java中文社群”关注我哟加个“星标”&#xff0c;一起成长&#xff0c;做牛逼闪闪的技术人JVM ≠ Japanese Videos Man写这篇的主要原因呢&#xff0c;就是为了能在简历上写个“熟悉JVM底层结构”&#xff0c;另一个原因就是能让读我文章的大家也写上这句话&#xf…

虹软安卓人脸识别初学

1_下载SDK 进入虹软官网&#xff1a; 点击人脸识别SDK 进入开发者中心&#xff08;注册登录&#xff09; 新建应用并添加SDK 输入相应信息&#xff0c;确认 下载sdk 2_run示例代码注意事项 跑不起来的解决方法&#xff08;SDK版本不一致&#xff09; 3_激活并使用

css圆在中心根据宽度缩放_根据CSS中的容器宽度重新缩放字体

css圆在中心根据宽度缩放Introduction: 介绍&#xff1a; Dealing with fonts is a very interesting thing to do as fonts bring out the appearance of your website or a web page so you must choose the ideal fonts for your website or web page that helps in making…

Java中不可或缺的59个小技巧,贼好用!

来源&#xff1a;https://blog.dogchao.cn/?p70《Effective JavaJava》名著&#xff0c;必读。如果能严格遵从本文的原则&#xff0c;以编写API的质量来苛求自己的代码&#xff0c;会大大提升编码素质。以下内容只记录了我自己整理的东西&#xff0c;还是建议读原文。为了聚焦…

第一次使用Sourcetree成功上传gitee记录

第一次使用Sourcetree成功上传gitee记录2_克隆gitee仓库到本地1_设置密钥公钥3_上传本地工作区进而上传到gitee4_最后一步&#xff0c;将文件从本地master提交到gitee5_小问题汇总5.1_git远端打不开5.2_当有多个仓库在使用时设置多个密钥公钥5.3_账户公钥和仓库公钥使用ssh密钥…

SUBSTR函数的使用

http://docs.oracle.com/cd/E11882_01/server.112/e41084/functions181.htm#i87066Substr语法&#xff1a;substr函数返回字符的部分&#xff0c;从postition开始定位&#xff0c;返回可选的字符长度substring_length。substr根据char字符集的字节数来计算长度。substrb则使用位…

坑爹的 Lombok,把我害惨了!

来源&#xff1a;juejin.im/post/6881432532332576781序言去年在项目当中引入了Lombok插件&#xff0c;着实解放了双手&#xff0c;代替了一些重复的简单工作(Getter,Setter,toString等方法的编写)&#xff0c;但是&#xff0c;在使用的过程当中&#xff0c;也发现了一些坑&…

数据结构学习笔记(六)链表算法题

假期结束&#xff0c;看点题目。 第一题 问题 设顺序表用数组A[]表示&#xff0c;表中元素存储在数组下标1~mn的范围内&#xff0c;前m个元素递增有序&#xff0c;后n个元素递增有序&#xff0c;设计一个算法&#xff0c;使得整个顺序表有序。 &#xff08;1&#xff09;给出算…

安卓第一次搭建C/S架构

1_数据库 2_服务端 服务端简单搭建准入门 使用json&#xff0c;导入jar包复制这段内容后打开百度网盘手机App&#xff0c;操作更方便哦 提取码&#xff1a; 3afj 在项目中建一个文件夹并粘贴进去 json与list的互转&#xff1a; import com.alibaba.fastjson.JSON;import j…

面试官不讲武德,竟然问了我18个JVM问题!

前言GC 对于Java 来说重要性不言而喻&#xff0c;不论是平日里对 JVM 的调优还是面试中的无情轰炸。这篇文章我会以一问一答的方式来展开有关 GC 的内容。本文章所说的 GC 实现没有特殊说明的话&#xff0c;默认指的是 HotSpot 的。我先将十八个问题都列出来&#xff0c;大家可…

2月第3周国内域名商TOP10:爱名网排名升至第八

IDC评述网&#xff08;idcps.com&#xff09;02月26日报道&#xff1a;根据WebHosting.info公布的最新数据显示&#xff0c;在2月第3周&#xff0c;国内域名商域名总量十强总体呈下降趋势。其中&#xff0c;降幅最大的是DNSPod&#xff0c;净减16,762个。另外&#xff0c;中国数…

Android JSON数据与实体类之间的相互转化-------GSON的简单用法

Android JSON数据与实体类之间的相互转化-------GSON的用法1_Gson的导入1.1_方法一&#xff1a;直接导入jar包1.2_方法二&#xff1a;引入依赖2_json形式的字符串互转实体对象2.1_json字符串与单个实体对象互转2.2_json与list互转3_遇到的问题3.1_前后端对象成员变量类型不一致…

5种SpringBoot热部署方式,你用哪种?

来源 | my.oschina.net/ruoli/blog/1590148Spring Boot 中 5 种热部署方式如下&#xff1a;1、模板热部署2、使用调试模式Debug实现热部署3、spring-boot-devtools4、Spring Loaded5、JRebel接下来我们分别来看。1、模板热部署在 Spring Boot 中&#xff0c;模板引擎的页面默认…

ContextMenu长按事件

/* ContextMenu菜单就是长按某一个组件&#xff0c;就会在屏幕的中间弹出ContextMenu&#xff0c;这里设置为长按文本框弹出ContextMenu菜单*/public class MyContextMenu extends AppCompatActivity {/** Called when the activity is first created. */final static int CONT…

熬夜都要看完的 Spring 干货!

在 Java 后端框架繁荣的今天&#xff0c;Spring 无疑是最最最火热&#xff0c;也是必不可少的开源框架&#xff0c;像腾讯、阿里、字节跳动等一线互联网公司都选择 Spring 作为基础的开发框架。而 Spring 生态圈里最让人兴奋的莫过于 Spring Boot 框架。他简化了使用 Spring 的…