贪心算法 – 柠檬水找零
题目重现
原题链接:力扣_柠檬水找零
在柠檬水摊上,每一杯柠檬水的售价为
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。
读懂题目
请注意这里的找零场景一共有三个注意点:
- 收钱金额:5元、10元、20元
- 找零金额:5元、15元
- 开始手头没有任何零钱(即第一人只能支付5元,否则找零失败)
贪心场景
上面我们得知,一共有两种找零金额不同的情况,5元和15元,两者分别对应收钱金额为10元和20元的场景。其中找零金额为15元时,有两种情况可以凑出这15元零钱:
- 5 + 5 + 5
- 10 + 5
对于这两种情况,当我们同时有足够的10元和5元零钱时,自然会优先选择将10元找零。因为当需要找零5元的场景时,手里有10元整币也无法正确找零,所以5元金额的整币的保留优先级要高于10元整币。
代码示例
class Solution {
public:
bool lemonadeChange(vector<int>& bills) {
int five = 0, ten = 0;
for(auto e: bills)
{
if(e == 5)
{
five++;
}
else if(e == 10)
{
if(five != 0)
{
five--;
ten++;
}
else{
return false;
}
}
else{
// e == 20
if(ten != 0)
{
if(five != 0)
{
ten--;
five--;
}
else{
return false;
}
}
else if(five >= 3)
{
five -= 3;
}
else{
return false;
}
}
}
return true;
}
};