LeetCode·860.柠檬水找零·贪心

链接:https://leetcode.cn/problems/lemonade-change/solution/by-xun-ge-v-t6ks/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 

题目

 

示例

 

思路

解题思路
这道题目刚一看,可能会有点懵,这要怎么找零才能保证完整全部账单的找零呢?

但仔细一琢磨就会发现,可供我们做判断的空间非常少!

只需要维护三种金额的数量,5,10和20。

有如下三种情况:

  • 情况一:账单是5,直接收下。
  • 情况二:账单是10,消耗一个5,增加一个10
  • 情况三:账单是20,优先消耗一个10和一个5,如果不够,再消耗三个5

此时大家就发现 情况一,情况二,都是固定策略,都不用我们来做分析了,而唯一不确定的其实在情况三。
而情况三逻辑也不复杂甚至感觉纯模拟就可以了,其实情况三这里是有贪心的。

账单是20的情况,为什么要优先消耗一个10和一个5呢?

因为美元10只能给账单20找零,而美元5可以给账单10和账单20找零,美元5更万能!

所以局部最优:遇到账单20,优先消耗美元10,完成本次找零。全局最优:完成全部账单的找零。

局部最优可以推出全局最优,并找不出反例,那么就试试贪心算法!

代码

bool lemonadeChange(int* bills, int billsSize){
    int five = 0, ten = 0, twenty = 0;
    for (int i = 0; i < billsSize; i++) {
        // 情况一
        if (bills[i] == 5) five++;
        // 情况二
        if (bills[i] == 10) {
            if (five <= 0) return false;
            ten++;
            five--;
        }
        // 情况三
        if (bills[i] == 20) {
            // 优先消耗10美元,因为5美元的找零用处更大,能多留着就多留着
            if (five > 0 && ten > 0) {
                five--;
                ten--;
                twenty++; // 其实这行代码可以删了,因为记录20已经没有意义了,不会用20来找零
            } else if (five >= 3) {
                five -= 3;
                twenty++; // 同理,这行代码也可以删了
            } else return false;
        }
    }
    return true;
}

作者:xun-ge-v
链接:https://leetcode.cn/problems/lemonade-change/solution/by-xun-ge-v-t6ks/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值