问题是用于说明动态编程的流行问题,如下所示。我们拥有每种面值1,3和5的无限硬币。我们希望最小数量的硬币获得金额N.
我知道动态编程方法,我们从基础案例中构建解决方案。但我想看看如何编写纯粹的递归解决方案。对于N = 11和面额= [1,3,5],我能够轻松地手工完成。但出于某种原因,我无法完成以下工作。
def minNumberOfCoins(amount, denominations):
if amount <= 0:
return(0)
if amount in denominations:
return(1)
else:
listToExamine = list(filter(lambda x: x > 0, map(lambda x: amount - x, denominations)))
print(listToExamine)
minVal = min(listToExamine, key=lambda x: 1 + minNumberOfCoins(x, denominations))
return(minVal)
据我所知,逻辑与我在纸上所做的相同。 Python的递归中是否存在一些我不知道的细微差别,或者是否存在一些我遗漏的微妙内容?谢谢!
答案 0 :(得分:1)
这种实现似乎更直接:
def minNumberOfCoins(amount, denominations):
if amount <= 0:
return(0)
if amount in denominations:
return(1)
for d in sorted(denominations, reverse=True):
if d <= amount:
return 1 + minNumberOfCoins(amount - d, denominations)
答案 1 :(得分:1)
更具可读性的方法。你不应该将map
或filter
与lambdas混在一起。条件理解和生成器通常是更好的选择:
def min_coins(amount, denominations):
# these two base cases seem to cover more edge cases correctly
if amount < 0:
return None
if amount == 0:
return 0
tries = (min_coins(amount-d, denominations) for d in denominations)
try:
return 1 + min(t for t in tries if t is not None)
except ValueError: # the generator in min produces no values
return None
min_coins(11, [1,3,5])
# 3