【Lintcode】1509. Lemonade Change(配数学证明)

题目地址:

https://www.lintcode.com/problem/lemonade-change/description

有个柠檬水摊,每瓶水价格是 5 5 5元。有一列顾客来买水,每次他们会支付 5 , 10 5,10 5,10 20 20 20元。摊贩一开始没有钱,但每次必须给顾客正确找零。给定顾客手里的钱的序列,问该序列是否可以实现正确找零。

用两个变量存摊贩手里有多少 5 5 5 10 10 10元( 20 20 20元钞票数量不用存,因为找零用不上)。如果顾客手里是 5 5 5元,那直接计数加 1 1 1;如果顾客手里是 10 10 10元,那此时摊贩手里必须有 5 5 5元找零,如果没有则返回false,否则将 5 5 5的计数减 1 1 1,并将 10 10 10的计数加 1 1 1;如果顾客手里是 20 20 20元,则先尽量找 10 + 5 10+5 10+5,如果找不了,则找 5 + 5 + 5 5+5+5 5+5+5,如果还找不了,则返回false。最后如果能安全遍历完序列,则返回true。

算法正确性证明:
这里用到贪心的思想,在于顾客手里 20 20 20元的时候,要优先找零 10 + 5 10+5 10+5而不是 5 + 5 + 5 5+5+5 5+5+5。首先,如果返回true,那一定存在合法找钱方案,这一点很显然。如果存在合法找钱方案,找到第一次与贪心法不同的找钱的时刻,说明这种方案找的钱是 5 + 5 + 5 5+5+5 5+5+5而不是贪心法的 10 + 5 10+5 10+5,此时,我们将这里的 5 + 5 5+5 5+5替换为 10 10 10,后面也是这样替换,如果哪里必须要用到 10 10 10了,那么就用 5 + 5 5+5 5+5顶上去。这样的方案显然也合法,它就被调整成了贪心方案,而贪心算法是返回true的,所以算法正确。

代码如下:

import java.util.List;

public class Solution {
    /**
     * @param bills: the Bill
     * @return: Return true if and only if you can provide every customer with correct change.
     */
    public boolean lemonadeChange(List<Integer> bills) {
        // Write your code here.
        int five = 0, ten = 0;
        for (int i = 0; i < bills.size(); i++) {
            int cur = bills.get(i);
            if (cur == 5) {
                five++;
            } else if (cur == 10) {
                five--;
                if (five < 0) {
                    return false;
                }
                ten++;
            } else {
                if (five > 0 && ten > 0) {
                    five--;
                    ten--;
                } else if (five >= 3) {
                    five -= 3;
                } else {
                    return false;
                }
            }
        }
        
        return true;
    }
}

时间复杂度 O ( n ) O(n) O(n) n n n为顾客数量,空间 O ( 1 ) O(1) O(1)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值