[路飞]_LeetCode题860柠檬水找零

142 阅读2分钟

题目描述

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

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

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

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

 

示例 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 美元的钞票。 对于接下来的 2 位顾客,我们收取一张 10 美元的钞票,然后返还 5 美元。 对于最后一位顾客,我们无法退回 15 美元,因为我们现在只有两张 10 美元的钞票。 由于不是每位顾客都得到了正确的找零,所以答案是 false。 示例 3:

输入:bills = [5,5,10] 输出:true 示例 4:

输入:bills = [10,10] 输出:false  

提示:

1 <= bills.length <= 105 bills[i] 不是 5 就是 10 或是 20 

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/le… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解思路

这道题是一个很简单的找零问题,题中顾客付款面额只有5、10、20,那么需要找零的是10和20面额的,因为我们不需要关心20的数量,所以不用对20面额计数,所以我们只需要关心当付款为10或20的顾客当时我们手中的钱是否足以找零即可。

  1. 第一个顾客如果不是付款5元则直接找零失败。
  2. 当付款10的顾客,我们只需要直到此时手中是否存在5元面额,存在则可以找零,5元数量-1,10元+1,不存在则找零失败。
  3. 当付款20的顾客,为我们优先选择10+5的方式找零,如果10和5都有则5元-1,10元-1,如果没有10元那么我们判断5元数量是否大于2,大于2则一定能有15元找零,除了这两种情况均为找零失败。

题解代码

 * @lc app=leetcode.cn id=860 lang=javascript
 *
 * [860] 柠檬水找零
 */

// @lc code=start
/**
 * @param {number[]} bills
 * @return {boolean}
 */
var lemonadeChange = function(bills) {
  //初始手中没有零钱,第一个顾客只要不是5元就不满足完全找零
  if(bills[0] > 5) return false;

  //由于顾客只有5、10/20三种面额,5元不需要找零,
  //我们只需要关心付款10和20的顾客在当前手中的5和10的数量是否可以找零即可
  let cnt5 = cnt10 = 0;
  for (let i = 0; i < bills.length; i++) {
    switch (bills[i]) {
      case 5:
        cnt5++;//不需找零,手中5元面额的数量+1
        break;
      case 10:
        //10元情况只要手中存在5元面额即可找零
        if(cnt5){
          cnt5--;//找零后手中5元面额数量-1
          cnt10++;//找零后手中10元面额数量+1
        }else{
          return false;//没有5元面额无法找零
        }
        break;
      default:
        //20面额需要找零15,15可以是10+5或5+5+5
        //当有10元面额的时候优先使用10+5找零
        //当没有10元面额时候判断是否5元面额数量够3个,不够3个则找零失败
        if(cnt5 && cnt10){
          cnt5--;//找零后手中5元面额数量-1
          cnt10--;//找零后手中10元面额数量-1
        }
        else if(cnt5 > 2){
          cnt5 = cnt5 - 3;//没有10元只有5元且5元数量大于3找零成功,5元面额数-3
        }else{
          return false;//找零失败
        }
        break;
    }
  }
  return true;//bills循环结束则所有人成功找零
};
// @lc code=end