[路飞]_leetcode刷题_860. 柠檬水找零

248 阅读2分钟

题目

860. 柠檬水找零

在柠檬水摊上,每一杯柠檬水的售价为 5 美元。顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。

每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5 美元。

注意,一开始你手头没有任何零钱。

给你一个整数数组 bills ,其中 bills[i] 是第 i 位顾客付的账。如果你能给每位顾客正确找零,返回 true ,否则返回 false 。

思路:

  1. 申请一个pokets数组,作为我们的口袋,遍历目标数组,等同于大家来买柠檬水付钱
  2. 当遇到5,则往pokets里放,
  3. 遇到10,则判断是否至少有一张5,没有则生意直接没法做return false,如果有,则放入一张10,拿出一张5
  4. 遇到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;
};

image.png

耗时简直高到爆炸。。。

那么考虑一下怎么优化

首先分析,我们的耗时主要耗在了频繁的splice处理数组导致的,那可否不用数组呢?

当然可以

生意能不能做,我们其实只要考虑收钱时,手上有没有足够的5和10,那我们只记录5和10的张数其实就够了

逻辑大致一样,修改为如下

  1. 申明两个变量,five和ten,记录口袋里5元和10元的张数,然后开始遍历目标数组,开张做生意
  2. 遇到5,则手里five++
  3. 遇到10,则判断是否至少有一张5,没有则生意直接没法做return false,如果有,则10++,5--
  4. 遇到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;
};