题目
860. 柠檬水找零
在柠檬水摊上,每一杯柠檬水的售价为 5 美元。顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。
每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5 美元。
注意,一开始你手头没有任何零钱。
给你一个整数数组 bills ,其中 bills[i] 是第 i 位顾客付的账。如果你能给每位顾客正确找零,返回 true ,否则返回 false 。
思路:
- 申请一个pokets数组,作为我们的口袋,遍历目标数组,等同于大家来买柠檬水付钱
- 当遇到5,则往pokets里放,
- 遇到10,则判断是否至少有一张5,没有则生意直接没法做return false,如果有,则放入一张10,拿出一张5
- 遇到20,则首先判断是否有一张10和一张5,有则拿出,放入一张20,没有则判断是否有三张5,有则拿出,放进一张20,否则生意没法做return false
直接上最最暴力代码:
/**
* @param {number[]} bills
* @return {boolean}
*/
var lemonadeChange = function(bills) {
let pockets = [];
for(let i=0;i<bills.length;i++){
if(bills[i] == 5){
pockets.push(5)
}else if(bills[i] == 10){
if(pockets.indexOf(5)>-1){
pockets.splice(pockets.indexOf(5),1);
pockets.push(10);
}else{
return false;
}
}else if(bills[i] == 20){
if(pockets.indexOf(10)>-1 && pockets.indexOf(5)>-1){
pockets.splice(pockets.indexOf(10),1);
pockets.splice(pockets.indexOf(5),1);
pockets.push(20);
}else if(pockets.indexOf(5)>-1){
let count = 0
for(let i=0;i<pockets.length;i++){
if(pockets[i] == 5){
count++;
}
}
if(count >=3){
pockets.splice(pockets.indexOf(5),1);
pockets.splice(pockets.indexOf(5),1);
pockets.splice(pockets.indexOf(5),1);
pockets.push(20);
}else{
return false;
}
}else{
return false;
}
}
}
return true;
};
耗时简直高到爆炸。。。
那么考虑一下怎么优化
首先分析,我们的耗时主要耗在了频繁的splice处理数组导致的,那可否不用数组呢?
当然可以
生意能不能做,我们其实只要考虑收钱时,手上有没有足够的5和10,那我们只记录5和10的张数其实就够了
逻辑大致一样,修改为如下
- 申明两个变量,five和ten,记录口袋里5元和10元的张数,然后开始遍历目标数组,开张做生意
- 遇到5,则手里five++
- 遇到10,则判断是否至少有一张5,没有则生意直接没法做return false,如果有,则10++,5--
- 遇到20,则首先判断是否有一张10和一张5,有则10--,5--,没有则判断是否有三张5,有则 five -= 3,否则生意没法做return false。
过程中并不用考虑20的数量。
代码如下:
/**
* @param {number[]} bills
* @return {boolean}
*/
var lemonadeChange = function(bills) {
let five = 0, ten = 0;
for(let i=0;i<bills.length;i++){
if(bills[i] == 5){
five++;
}else if(bills[i] == 10){
if(five<=0) return false;
five--;
ten++;
}else if(bills[i] == 20){
if(ten >0 && five >0){
five--;
ten--;
}else{
five -= 3;
}
if(five<0||ten<0){
return false
}
}
}
return five>=0 && ten >=0;
};