这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战
以前我也曾经刷过一段时间的leetcode,后来因为比较忙,所以停了好久了。现在来开始重新满满刷起来,毕竟只是位前端,还是继续使用JavaScript进行编写代码(最熟悉一些)
贪心算法
贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解 。
贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择
我对于贪心算法的题目总是认为其解答是很巧妙的,有时候经常出乎你的意料,比如:《第三大的数,两地调度》,这里面两地调度的问题如果想通了,其实就非常简单,关键就是在于自己的思路。
柠檬水找零
柠檬水找零问题是贪心算法当中一道非常经典的问题
题目:leetcode地址
在柠檬水摊上,每一杯柠檬水的售价为 5 美元。顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。 每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5 美元。 注意,一开始你手头没有任何零钱。
给你一个整数数组 bills ,其中 bills[i] 是第 i 位顾客付的账。如果你能给每位顾客正确找零,返回 true ,否则返回 false 。
示例:
输入:bills = [5,5,5,10,20]
输出:true
解释: 前 3 位顾客那里,我们按顺序收取 3 张 5 美元的钞票。
第 4 位顾客那里,我们收取一张 10 美元的钞票,并返还 5 美元。
第 5 位顾客那里,我们找还一张 10 美元的钞票和一张 5 美元的钞票。
由于所有客户都得到了正确的找零,所以我们输出 true。
这道题目其实本身比较简单,主要就是看10元和20元的找零情况,当前我们所拥有的零钱是否满足需要找的零钱条件。
| 钱 | 对应 |
|---|---|
| 5元 | 不需要找零,直接收下 |
| 10元 | 需要找零一张5元 |
| 20元 | 两种方案:1. 一张5元 + 一张10元 2. 三张5元 |
本题在贪心算法上的运用就是在于20元的找零方案,是要使用哪一种更加好。贪心算法就是要达到局部最优解。
当然本题肯定是优先使用10 + 5这种方式,因为5元在这里是对10元和20元都通用的,而10元只是给20元会用到,所以肯定先消耗10元。
作答:(虽然我写的不一定是最优代码,但总算还是能够成功通过测试💎)
var lemonadeChange = function(bills) {
// fives 5元数量, tens 10元数量
let fives = 0, tens = 0;
if (bills[0] != 5) return false;
for(let item of bills) {
if (item == 5) { fives ++; }
else if (item == 10) {
if (fives > 0) {
fives --;
tens ++;
} else {
return false;
}
} else if (item == 20) {
if (tens > 0 && fives > 0) {
fives --;
tens --;
} else if (fives > 2) {
fives -= 3;
} else {
return false;
}
}
}
return true;
};