我写了一个名为change
的函数,它接收int
和硬币列表。
它以递归方式检查创建该金额所需的最少金币数量并返回此数字。现在我正在尝试修改此功能以获取相同的输入,而是返回一个列表,其中包含硬币数量和使用的硬币列表。
def change(amount, coins):
if amount == 0:
return 0
if coins == []:
return float("inf")
if coins[0] > amount:
return change(amount, coins[1:])
use_it = 1+change(amount-coins[0], coins)
lose_it = change(amount, coins[1:])
return min(use_it, lose_it)
我开始修改此代码但我不确定如何操作返回值,因为它是一个列表:
def giveChange(amount, coins):
if amount == 0:
return [0, []]
if coins == []:
return [float("inf"), []]
if coins[0] > amount:
return giveChange(amount, coins[1:])
use_it = 1 + giveChange(amount-coins[0], coins)
lose_it = giveChange(amount, coins[1:])
listOfCoins =
return [min(use_it, lose_it), listOfCoins]
到目前为止,我有这个,但我的use_it行是错误的,因为该函数现在返回一个列表。我可以这么做吗:
use_it = 1 + giveChange(amount-coins[0], coins)[0]
我不知道如何建立硬币列表,以便我可以在最后用硬币返还它。
答案 0 :(得分:2)
返回一个列表,其中包含硬币数量和使用的硬币列表。
我认为这就是你要找的东西:
def giveChange(amount, coins):
if amount == 0:
return [0, []]
if coins == []:
return [float("inf"), []]
if coins[0] > amount:
return giveChange(amount, coins[1:])
[use_it_amt, use_it_list] = giveChange(amount-coins[0], coins)
[lose_it_amt, lose_it_list] = giveChange(amount, coins[1:])
if use_it_amt+1 < lose_it_amt:
use_it_list.append(coins[0])
return [use_it_amt+1, use_it_list]
else:
return [lose_it_amt, lose_it_list]
在这里你可以看到它有效:https://repl.it/Bn2T
因为这是动态编程,所以使用memoization表来防止重新计算子问题是好事,而且它依赖于堆栈,如果递归调用的数量太大,它会给你StackOverflow。
答案 1 :(得分:1)
只需在整个代码中正确处理第二个参数,唯一困难的是use_it
需要在硬币数量上加1并将coin[0]
添加到使用的硬币列表中。 min
需要考虑并锁定第一个参数:
def give_change(amount, coins):
if amount == 0:
return [0, []]
if coins == []:
return [float('inf'), []]
if coins[0] > amount:
return give_change(amount, coins[1:])
use_it = [x+y for x,y in zip(give_change(amount-coins[0], coins), [1,[coins[0]]])]
lose_it = give_change(amount, coins[1:])
return min(use_it, lose_it, key=lambda x: x[0])
>>> give_change(53, [1, 2, 5, 10, 25, 50, 100])
[3, [50, 2, 1]]
采用更加动态的编程方法,你可以在没有递归的情况下完成。我假设您可以重复使用硬币(因为您的原始代码也可以重复使用硬币)。 give_change
现在返回所有可以通过硬币获得金额的方式,您只需min
key=len
:
def give_change(amount, coins):
ways = [list() for _ in range(0, amount+1)]
ways[0].append([])
for coin in coins:
for i, x in enumerate(range(coin, amount+1)):
ways[x].extend(l+[coin] for l in ways[i])
return ways[amount]
>>> give_change(3, [1, 2, 5, 10, 25, 50, 100])
[[1, 1, 1], [1, 2]]
>>> min(give_change(3, [1, 2, 5, 10, 25, 50, 100]), key=len)
[1, 2]
>>> min(give_change(53, [1, 2, 5, 10, 25, 50, 100]), key=len)
[1, 2, 50]