[LeetCode] 860. Lemonade Change 買檸檬找零



At a lemonade stand, each lemonade costs `$5`. 

Customers are standing in a queue to buy from you, and order one at a time (in the order specified by bills).

Each customer will only buy one lemonade and pay with either a $5$10, or $20 bill.  You must provide the correct change to each customer, so that the net transaction is that the customer pays $5.

Note that you don't have any change in hand at first.

Return true if and only if you can provide every customer with correct change.

Example 1:

Input: [5,5,5,10,20]
Output: true
Explanation:
From the first 3 customers, we collect three $5 bills in order.
From the fourth customer, we collect a $10 bill and give back a $5.
From the fifth customer, we give a $10 bill and a $5 bill.
Since all customers got correct change, we output true.

Example 2:

Input: [5,5,10]
Output: true

Example 3:

Input: [10,10]
Output: false

Example 4:

Input: [5,5,10,10,20]
Output: false
Explanation:
From the first two customers in order, we collect two $5 bills.
For the next two customers in order, we collect a $10 bill and give back a $5 bill.
For the last customer, we can't give change of $15 back because we only have two $10 bills.
Since not every customer received correct change, the answer is false.

Note:

  • 0 <= bills.length <= 10000
  • bills[i] will be either 510, or 20.

這道題說是有很多檸檬,每個賣5刀,顧客可能會提供5刀,10刀,20刀的鈔票,我們剛開始的時候並沒有零錢,只有收到顧客的5刀,或者 10 刀可以用來給顧客找錢,當然如果第一個顧客就給 10 刀或者 20 刀,那么是無法找零的,這里就問最終是否能夠都成功找零。博主最先想到的方法是首先用一個 HashMap 來分別統計出5刀,10 刀,和 20 刀鈔票的個數,然后再來統一分析是否能成功找零。由於 10 刀的鈔票需要5刀的找零,20 刀的鈔票可以用1張 10 刀和1張5刀,或者3張5刀的鈔票,所以至少需要1張5刀,那么當前5刀的個數一定不能小於 10 刀和 20 刀的個數之后,否則無法成功找零。由於 20 刀可以用 10 刀來找零,每個 10 刀可以節省兩個5刀,但是為了獲得每張 10 刀,我們還得付出一張5刀的找零,所以實際上用 10 刀來找零只能省下1張5刀鈔票,但是假如 10 刀的個數不夠,那么每張 20 刀的鈔票還是需要3張5刀的鈔票來找零的,所以判斷若5刀鈔票的個數小於 20 刀鈔票個數的三倍減去 10 刀鈔票的個數,直接返回 false。for 循環退出后返回 true,參見代碼如下:
解法一:
class Solution {
public:
    bool lemonadeChange(vector<int>& bills) {
		unordered_map<int, int> cnt;
		for (int bill : bills) {
            ++cnt[bill];
            if (cnt[5] < cnt[20] + cnt[10]) return false;
            if (cnt[5] < 3 * cnt[20] - cnt[10]) return false;
        }
        return true;
    }
};

實際上我們並不需要一直保留所有鈔票的個數,當某些鈔票被當作零錢給了,就沒有必要繼續留着它們的個數了。其實上我們只關心當前還剩余的5刀和 10 刀鈔票的個數,用兩個變量 five 和 ten 來記錄。然后遍歷所有的鈔票,假如遇到5刀鈔票,則 five 自增1,若遇到 10 刀鈔票,則需要找零5刀,則 five 自減1,ten 自增1。否則遇到的就是 20 刀的了,若還有 10 刀的鈔票話,就先用 10 刀找零,則 ten 自減1,再用一張5刀找零,five 自減1。若沒有 10 刀了,則用三張5刀找零,five 自減3。找零了后檢測若此時5刀鈔票個數為負數了,則直接返回 false,參見代碼如下:
解法二:
class Solution {
public:
    bool lemonadeChange(vector<int>& bills) {
		int five = 0, ten = 0;
        for (int bill : bills) {
            if (bill == 5) ++five;
            else if (bill == 10) { --five; ++ten; }
            else if (ten > 0) { --ten; --five; }
            else five -= 3;
            if (five < 0) return false;
        }
        return true;
    }
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/860


參考資料:

https://leetcode.com/problems/lemonade-change/

https://leetcode.com/problems/lemonade-change/discuss/143719/C%2B%2BJavaPython-Straight-Forward


[LeetCode All in One 題目講解匯總(持續更新中...)](https://www.cnblogs.com/grandyang/p/4606334.html)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM