力扣习题:860. 柠檬水找零
题目超链接https://leetcode-cn.com/problems/lemonade-change/
解题思路:
1.已知关系当前余额=balance+5,(即每次只能交易一笔,即+5元)
2.已知change=0,则无需找零。
3.已知交易前的余额小于change,则不能找零。
4.上面3点容易得出。但余额面值与change零钱的匹配关系是否满足,则是难点。
故如何该算法的关系点:计算change与余额面值的匹配关系。
根据题目已知bills[i] 不是 5 就是 10 或是 20 ,即表明,找零change只有三个值即5,10,15
如果要满足这三个值的找零,则余额面值里面需有对应的面值,否则无法找零
通过上面的分析,找到了change与余额面值的匹配关系,但如何保证余额面值balance_list当前状态正确呢?
即更新余额面值balance_list的场景
1.如果无需找零,即change=0时,直接append(5)
2.如果需要找零,则remove元素,则append新的面值
`class Solution:
def lemonadeChange(self, bills) -> bool:
#设余额的初始值为0
balance=0
balance_list=[]
for id,item in enumerate(bills):
#当前找零=实际收款-5
change=item-5
#交易前的余额小于change,则不能找零。
if balance<change:
return False
# 当前余额=balance+5
balance=balance+5
#change=0,则无需找零。
if change==0:
#无需找零,即change=0时,直接append(5)
balance_list.append(item)
continue
#change与余额面值的匹配关系
elif change==5:
if 5 not in balance_list:
return False
else:
#需要找零,则remove元素,则append新的面值
balance_list.remove(5)
balance_list.append(item)
continue
elif change==10:
if 10 in balance_list:
balance_list.remove(10)
balance_list.append(item)
continue
elif balance_list.count(5)>=2:
balance_list.remove(5)
balance_list.remove(5)
balance_list.append(item)
continue
else:
return False
elif change==15:
if balance_list.count(5)>=3:
balance_list.remove(5)
balance_list.remove(5)
balance_list.remove(5)
balance_list.append(item)
continue
elif 10 in balance_list and 5 in balance_list:
balance_list.remove(10)
balance_list.remove(5)
balance_list.append(item)
continue
else:
return False
return True
优化版本: 解题思路 由于找零【5,10,15】,故实质转换为:记录5,10的个数,如果有一个透支了,即说明不能满足找零
def lemonadeChange(bills):
#i记录5出现的次数
#j记录10出现的次数
#一开始余额为0,则5和10的面值都没有
i=j=0
for k in bills:
if k5:i+=1;#无需要找零
elif k10:j+=1;i-=1 #如需找5元,则i-1
else: #k20
if j1:i-=3 #找零15,则一次10,再取一次1
elif j==0:i-=1 #找零15,则取3次5
#如果i和j出现负数,则代表不能取
if i<0 or j<0:
return False
return True
`
我觉得代码有点缺陷,如果是20块钱,我们应该优先考虑找零一张10块的 和一张5块的,而不是先找3张5块的】 因为5块的比10块钱要更加灵活,如果你全把5块换光了,就不好找后面的零钱了