LeetCode-860-easy-柠檬水找零(贪心,模拟)

[toc]

关键字

模拟求解,贪心

题目描述

在柠檬水摊上,每一杯柠檬水的售价为 5 美元。

顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。

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

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

如果你能给每位顾客正确找零,返回 true ,否则返回 false 。

分析

  • 题目描述为按照顺序进行找零,进行模拟,只用维护每次找零时商家的零钱状态,对于每位顾客的付账,进行找零
  • 进行找零时有多种方案,在本题中,优先用面值大的来找零是最佳方案。

直观上:总额相同的零钱比整钱的灵活性更强
分析:
本题的货币面值:,可能的找零值为, 因此不会用来找零(如:100RMB不会用来找零)

现证明在货币总值相同的情况下,更多的面值货币会带来更便于找零

对于找零值,只能用来找零
对于找零值,可以用找零,或者用找零

解题思路

模拟+贪心:
维护商家的零钱状态,对于每次顾客的找零,优先使用面值为10的货币进行找零。

算法

INPUT: bills
OUTPUT: bool(是否可以找零)

money <- [0,0,0]
for bill in bills :
    bill -= 5
    ten = min( bill/10, money[1] )
    bill = bill - ten*10 
    five = min( bill/5, money[0] )
    bill = bill - five*5
    if ( bill > 0 )
        return false 
    money[1] -= ten
    money[0] -= five

return true 

数据结构

时间复杂度:
空间复杂度:

代码实现

class Solution {
public:
    bool lemonadeChange(vector& bills) {
        vector money(3) ;

        for ( int bill : bills ){
            int change = bill - 5 ;

            // 判断是否可以找零并记录最优找零方式
            int ten_count = min( change/10, money[1] ) ;
            int five_count_needed = ( change-10*ten_count )/5 ;
            if ( five_count_needed > money[0] ){
                return false ;
            }
            // 更新
            money[0] -= five_count_needed ;
            money[1] -= ten_count ;
            money[bill/10] ++ ;
        }
        return true ;
    }
};

思考与相关问题

1. 如果可以不按照排队顺序进行找零呢?

(例如:bills=[5,10,5,20,5,5], 按照排队顺序不能顺利找零)
sort之后在按照本题的大面值优先找零就可以么?(应该是的)

2. 如果面值更多样,相邻两个面值之间不全是2倍关系呢?

(例如:面值为5,10,20,50,100)
对于已排序的bills=[5,5,5,5,5,5,10,10,20,50]
45 = [(20+20+5),(20+10+10+5),(10+10+10+10+5),...]
对于45,优先使用面值大的仍然可行
95 = [(50+20+20+5),(50+20+10+10+5),(50+20+10+5+5),...]
问题就在于货币50不能直接用20来替换

3.相关题目

递归剪枝
leetcode-39-组合总和

4. 货币面值为什么按1、2、5来设置?

应该是为了方便人们携带。
携带尽量少的(纸张和重量),1-10的任意整数值都可以用两个数值进行+或-来得到,减法对应收付款双方。


PS.

  1. 相比较于其他已有的leetcode刷题笔记,我希望能够提供相关的解题分析和部分相关问题的链接,使得大家能获得一个较好的分析与相关问题的比较。

  2. 偶尔会进行类似题目的总结工作,有需要的读者可以对这份工作进行关注。

  3. 如果你发现有相关的错误或者表述不当不清晰的地方,请进行评论,我会尽快进行核对勘正。

你可能感兴趣的:(LeetCode-860-easy-柠檬水找零(贪心,模拟))