一日一练: 柠檬水找零

118 阅读2分钟

在柠檬水摊上,每一杯柠檬水的售价为 5 美元。顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5 美元。

思路:

    1. 遍历bills数组,判断当前支付费用是否能找零,同时也需要记录当前所拥有零钱数量。
    1. 判断条件:
    • 5元: 给5元的数量加1
    • 10元: 当前5 元数量是否不为0
      • 0则不能顺利找零,返回false
      • 顺利找零: 给10元数量加15元数量减1
    • 20元20有两种找零方式: 1. 10 + 5 2. 5 + 5 + 5。这里得优先使用第一种找零方式,因为这样竟可能多的保留了5的数量,会让后面的10可以找零。
      • 10 + 5 找零
        • 是否有1枚以上105元: 是的话,分别减少1枚10元和5元的数量增加120元
        • 是否有3枚以上5元数量: 是的话,减少3枚5元的数量,增加120元
        • 否则: 返回false
    1. 如果bills遍历结束也每天退出循环,直接返回true,表明当前所有账单已顺利找零
// 贪心算法
function lemonadeChange(bills: number[]): boolean {
    // 因为 20 无法作为零钱找出去,这里不需要申明其对应数量的变量
    let five = 0, ten = 0
    for(let i = 0; i < bills.length; i++) {
        let cur = bills[i]
        if (cur === 5) {
            five++
        } else if (cur === 10) {
            if (five > 0) {
                five--
                ten++
            } else {
                return false
            }
        } else {           
            if (five >= 1 && ten >= 1) {
                five--
                ten--
            } else if (five >= 3) {
                five -= 3
            } else  {
                return false
            }
        }
    }
    return true
};

// 时间复杂度 O(n); 空间复杂度O(1)