《代码随想录》Ⅷ 贪心算法 860. 柠檬水找零
努力学习!
题目:力扣链接
-
在柠檬水摊上,每一杯柠檬水的售价为
5
美元。顾客排队购买你的产品,(按账单bills
支付的顺序)一次购买一杯。每位顾客只买一杯柠檬水,然后向你付
5
美元、10
美元或20
美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付5
美元。注意,一开始你手头没有任何零钱。
给你一个整数数组
bills
,其中bills[i]
是第i
位顾客付的账。如果你能给每位顾客正确找零,返回true
,否则返回false
。
一、思想
这道题的核心思想是使用贪心算法,即在每一步选择中,尽可能多地使用现有的零钱来进行找零,以确保能够满足后续的找零需求。具体来说,当顾客支付10元或20元时,优先使用10元进行找零,因为10元只能用于找零5元,而5元可以用于更多的找零场景。
二、代码
/**
* 买卖柠檬ade问题
* 有四种面值的钞票:5,10,20,100。
* 你会得到一些钞票,然后需要返回正确的找零。
* 给定一个整数数组 bills,其中 bills[i] 是顾客支付的钞票面值,你需要返回找零的钞票数目最少的情况下,钞票数目能否正好找齐。
* 注意:
* 1. 0 <= bills.length <= 10^4
* 2. 1 <= bills[i] <= 10^4
*/
class Solution
{
public:
/**
* 判断是否能正好找齐
* @param bills 支付的钞票面值数组
* @return 是否能正好找齐
*/
bool lemonadeChange(vector<int> &bills)
{
// 记录5元和10元的钞票数量
int five = 0, ten = 0;
// 遍历所有支付的钞票
for (int i = 0; i < bills.size(); ++i) {
// 如果是5元钞票,数量加一
if (bills[i] == 5) {
five++;
}
// 如果是10元钞票
if (bills[i] == 10) {
// 如果没有足够的5元钞票,返回false
if (five <= 0) {
return false;
}
// 数量加一,5元钞票数量减一
ten++;
five--;
}
// 如果是20元钞票
if (bills[i] == 20) {
// 如果有足够的10元和5元钞票,数量减一,5元钞票数量减一
if (ten > 0 && five > 0) {
ten--;
five--;
}
// 如果没有足够的10元和5元钞票,但有足够的5元钞票,数量减三
else if (five >= 3) {
five -= 3;
}
// 如果既没有足够的10元和5元钞票,也没有足够的5元钞票,返回false
else {
return false;
}
}
}
// 如果能正好找齐,返回true
return true;
}
};
三、代码解析
1. 算法工作原理分解
1.1 初始化零钱数量
- 目的:记录当前拥有的5元和10元零钱的数量。
- 实现:使用两个变量
five
和ten
来分别记录5元和10元的数量,初始值均为0。
1.2 遍历支付账单
-
目的:根据顾客支付的金额进行找零,并更新零钱数量。
-
实现:
- 如果顾客支付5元,直接增加5元零钱的数量。
- 如果顾客支付10元,检查是否有足够的5元零钱,如果有,则减少5元零钱的数量并增加10元零钱的数量;否则,返回
false
。 - 如果顾客支付20元,优先使用10元和5元进行找零(如果有),否则使用三个5元进行找零。如果都无法满足,则返回
false
。
1.3 返回结果
- 目的:判断是否能够成功完成所有找零。
- 实现:如果遍历完所有账单后没有返回
false
,则返回true
,表示能够成功完成所有找零。
2. 关键点说明
2.1 贪心算法的应用
- 局部最优:在每一步找零时,尽可能多地使用现有的零钱,尤其是优先使用10元进行找零。
- 全局最优:通过局部最优的选择,确保能够完成所有找零,并且零钱的使用是最优的。
2.2 零钱的使用顺序
- 当顾客支付20元时,优先使用10元和5元进行找零,因为这样可以减少5元零钱的消耗,使得5元零钱能够用于更多的找零场景。
2.3 边界条件
- 如果顾客支付10元或20元时,没有足够的零钱进行找零,则直接返回
false
。
四、复杂度分析
-
时间复杂度:
O(n)
- 其中
n
是账单的数量。算法只需要遍历一次账单数组,因此时间复杂度为O(n)
。
- 其中
-
空间复杂度:
O(1)
- 只需要常数空间来记录5元和10元零钱的数量,因此空间复杂度为
O(1)
。
- 只需要常数空间来记录5元和10元零钱的数量,因此空间复杂度为
白展堂:人生就是这样,苦和累你总得选一样吧?哪有什么好事都让你一个人占了呢。 ——《武林外传》