题外话
今天有点崩溃了,算法题一个不会,压力有点大
所以说今天给大家讲解一下很经典的
贪心算法
正题
贪心算法
一.什么是贪心算法?
先提出贪心策略:解决问题的策略,局部最优->全局最优
1.把解决问题的过程分为若干步
2.解决每一步的时候,都选择当前看起来”最优的”算法
3.”希望”得到全局最优解
贪婪+鼠目寸光
二.贪心算法的特点
1.贪心策略提出
贪心策略的提出是没有固定标准以及模版
可能每一道题贪心策略都是不同的
2.贪心策略正确性
因为有可能”贪心策略是一个错误的方法 ”
正确的贪心策略,我们是需要”证明的”
三.学习贪心的方向
遇到不会的贪心题,很正常,把心态放平
学习的时候,把重点放到贪心策略上,把这个策略当成贪心策略
证明尽量要掌握
这里我们直接用一道类型题去作为讲解
例题
柠檬水找零
在柠檬水摊上,每一杯柠檬水的售价为 5
美元。
顾客排队购买你的产品,(按账单 bills
支付的顺序)一次购买一杯。
每位顾客只买一杯柠檬水,然后向你付 5
美元、10
美元或 20
美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5
美元。
注意,一开始你手头没有任何零钱。
如果你能给每位顾客正确找零,返回 true
,否则返回 false
。
示例 1:
输入:[5,5,5,10,20]
输出:true
解释: 前 3 位顾客那里,我们按顺序收取 3 张 5 美元的钞票。
第 4 位顾客那里,我们收取一张 10 美元的钞票,并返还 5 美元。
第 5 位顾客那里,我们找还一张 10 美元的钞票和一张 5 美元的钞票。
由于所有客户都得到了正确的找零
所以我们输出 true。
示例2:
输入:[5,5,10]
输出:ture
示例3:
输入:[10,10]
输出:false
解题步骤
一.题目解析
1.一杯柠檬水顾客要支付5美元
2.顾客是一个一个排队购买,而且每个顾客只卖一杯,顾客付钱只有三种,5美元,10美元,20美元
3.最开始我们手里没有任何钱
4.顾客一个一个排队买,我们手里的钱如果能找零就返回true,没办法找零就返回false
二.用贪心算法解决问题
找到局部最优解,也就是把手中的5美元留住,就是我们这里的最优解之一
请看下图,
三.写代码
public boolean text01(int[] bills)
{
//创建5元纸币数量,创建10元纸币为0
int fives=0;
int tens=0;
//循环进入bills
for (int i = 0; i < bills.length; i++) {
//如果顾客支付5元,则fives++
if (bills[i]==5)
{
fives++;
}
//如果顾客支付10元
if(bills[i]==10){
//如果5元纸币为0张,没法找钱,返回false
if(fives==0)
{
return false;
}
//如果5元纸币不为0张,则10元纸币++,五元纸币--
else {
tens++;
fives--;
}
}
//顾客如果支付20元
if (bills[i]==20)
{
//如果十元数量和五元数量都大于0,则先选择十元纸币--,五元纸币--
if (tens>0&&fives>0)
{
tens--;
fives--;
}
//如果是元纸币为0,五元纸币大于等于3
else if (tens==0&&fives>=3)
{
//则五元纸币-3
fives-=3;
}
//如果以上两种情况都不满足则直接返回false
else {
return false;
}
}
}
//循环结束,没有返回false则返回ture
return true;
}
四.证明
任何题都有最优解而且可能不止一种
我们这里是用贪心算法
在这道题中,贪心算法也绝对是最优解中的一个
当我们支付10元钱的时候,最优解和贪心算法是一样的,都是找五块钱
不一样的地方就是在支付20块找零的时候
证明如下图
小结
不多说了继续去学习后面内容了,压力真的拉满了!!
喜欢的麻烦给个三连支持下吧!!!(点赞关注收藏!!!)