由于顾客只可能给你三个面值的钞票,而且我们一开始没有任何钞票,因此我们拥有的钞票面值只可能是 5 美元,10 美元和 20 美元三种。基于此,我们可以进行如下的分类讨论。
-
5 美元,由于柠檬水的价格也为 5 美元,因此我们直接收下即可。
-
10 美元,我们需要找回 5 美元,如果没有 5 美元面值的钞票,则无法正确找零。
-
20 美元,我们需要找回 15 美元,此时有两种组合方式,一种是一张 10 美元和 5 美元的钞票,一种是 3 张 5 美元的钞票,如果两种组合方式都没有,则无法正确找零。当可以正确找零时,两种找零的方式中我们更倾向于第一种,即如果存在 5 美元和 10 美元,我们就按第一种方式找零,否则按第二种方式找零,因为需要使用 5 美元的找零场景会比需要使用 10 美元的找零场景多,我们需要尽可能保留 5 美元的钞票。
基于此,我们维护两个变量 five 和 ten 表示当前手中拥有的 5 美元和 10 美元钞票的张数,从前往后遍历数组分类讨论即可。
对于是否能正确找零,由于我们最后终是以 5 美元找零或不找零,所以只需判断 five 变量是否大于零即可。
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;
}
};