题目描述
在柠檬水摊上,每一杯柠檬水的售价为 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。 示例 3:
输入:bills = [5,5,10] 输出:true 示例 4:
输入:bills = [10,10] 输出:false
提示:
1 <= bills.length <= 105 bills[i] 不是 5 就是 10 或是 20
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/le… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解思路
这道题是一个很简单的找零问题,题中顾客付款面额只有5、10、20,那么需要找零的是10和20面额的,因为我们不需要关心20的数量,所以不用对20面额计数,所以我们只需要关心当付款为10或20的顾客当时我们手中的钱是否足以找零即可。
- 第一个顾客如果不是付款5元则直接找零失败。
- 当付款10的顾客,我们只需要直到此时手中是否存在5元面额,存在则可以找零,5元数量-1,10元+1,不存在则找零失败。
- 当付款20的顾客,为我们优先选择10+5的方式找零,如果10和5都有则5元-1,10元-1,如果没有10元那么我们判断5元数量是否大于2,大于2则一定能有15元找零,除了这两种情况均为找零失败。
题解代码
* @lc app=leetcode.cn id=860 lang=javascript
*
* [860] 柠檬水找零
*/
// @lc code=start
/**
* @param {number[]} bills
* @return {boolean}
*/
var lemonadeChange = function(bills) {
//初始手中没有零钱,第一个顾客只要不是5元就不满足完全找零
if(bills[0] > 5) return false;
//由于顾客只有5、10/20三种面额,5元不需要找零,
//我们只需要关心付款10和20的顾客在当前手中的5和10的数量是否可以找零即可
let cnt5 = cnt10 = 0;
for (let i = 0; i < bills.length; i++) {
switch (bills[i]) {
case 5:
cnt5++;//不需找零,手中5元面额的数量+1
break;
case 10:
//10元情况只要手中存在5元面额即可找零
if(cnt5){
cnt5--;//找零后手中5元面额数量-1
cnt10++;//找零后手中10元面额数量+1
}else{
return false;//没有5元面额无法找零
}
break;
default:
//20面额需要找零15,15可以是10+5或5+5+5
//当有10元面额的时候优先使用10+5找零
//当没有10元面额时候判断是否5元面额数量够3个,不够3个则找零失败
if(cnt5 && cnt10){
cnt5--;//找零后手中5元面额数量-1
cnt10--;//找零后手中10元面额数量-1
}
else if(cnt5 > 2){
cnt5 = cnt5 - 3;//没有10元只有5元且5元数量大于3找零成功,5元面额数-3
}else{
return false;//找零失败
}
break;
}
}
return true;//bills循环结束则所有人成功找零
};
// @lc code=end