[路飞] 20——leetcode - [860] 柠檬水找零

164 阅读3分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

860. 柠檬水找零

题目分析

在柠檬水摊上,每一杯柠檬水的售价为 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美元的找零组合

重复上述的判断,直到我们不能找零或者所有的顾客都购买完毕

示例

示例 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; // 返回可以找零
};