Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
题目分析
在柠檬水摊上,每一杯柠檬水的售价为 5 美元。顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。
每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5 美元。
注意: 一开始你手头没有任何零钱。
给你一个整数数组 bills ,其中 bills[i] 是第 i 位顾客付的账。如果你能给每位顾客正确找零,返回 true ,否则返回 false 。
思路讲解
找零只需要5美元和10美元的,定义两个变量Five和Ten来记录拥有的5美元及10美元钞票的数量 Five =0; Ten = 0;
获取每位顾客支付给我们的金额进行判断:
- 如果是5美元,不需要进行找零,直接Five+1
- 如果是10美元,需要判断是否有5美元的钞票
- 如果有,5美元的钞票数量减1,十美元的数量加1
- 如果没有,无法进行找零,返回false, 程序结束
- 如果是20美元,找零的方式可以分为两种:
- 一种是需要一张10美元和一张5美元
- 如果5美元和10美元各有一张,就能够进行找零,5美元和10美元对应的数量都减1
- 若美元10美元的钞票,就需要判断第二种情况,是否有3张5美元的钞票
- 另一种是需要3张5美元的钞票
- 如果有,则进行找零,5美元钞票的数量减3
- 如果美元,则无法进行找零,返回false,程序结束
由于5美元用到的情况比较多,需要尽可能的保留5美元的钞票, 所以优先考虑10美元加5美元的找零组合
- 一种是需要一张10美元和一张5美元
重复上述的判断,直到我们不能找零或者所有的顾客都购买完毕
示例
示例 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 美元的钞票。
对第3、4位顾客,我们收取一张 10 美元的钞票,然后返还 5 美元。
对最后一位顾客,我们无法退回 15 美元,因为我们现在只有两张 10 美元的钞票。
由于不是每位顾客都得到了正确的找零,所以答案是 false。
代码
/*
* @lc app=leetcode.cn id=860 lang=javascript
*
* [860] 柠檬水找零
*/
// @lc code=start
/**
* @param {number[]} bills
* @return {boolean}
*/
var lemonadeChange = function (bills) {
let five = 0, ten = 0;
if (bills[0] == 10 || bills[0] == 20) return false // 如果第一次是10或者20,直接返回false
for (const bill of bills) {
if (bill === 5) five++;
if (bill === 10) {
ten++;
five--;
}
if (bill === 20) {
if (ten && five) {
ten--;
five--;
} else if (five >= 3) {
five -= 3;
} else {
return false;
}
}
if (ten < 0 || five < 0) {
return false; // 不能找零的时候,退出循环
}
}
return true; // 返回可以找零
};