问题描述
def rec_coin_dynam(target,coins,kNown_results):
'''
INPUT: This funciton takes in a target amount and a list of possible coins to use.
It also takes a third parameter,kNown_results,indicating prevIoUsly calculated results.
The kNown_results parameter shoud be started with [0] * (target+1)
OUTPUT: Minimum number of coins needed to make the target.
'''
# Default output to target
min_coins = target
# Base Case
if target in coins:
kNown_results[target] = 1
return 1
# Return a kNown result if it happens to be greater than 1
elif kNown_results[target] > 0:
return kNown_results[target]
else:
# for every coin value that is <= than target
for i in [c for c in coins if c <= target]:
# Recursive call,note how we include the kNown results!
num_coins = 1 + rec_coin_dynam(target-i,kNown_results)
# Reset Minimum if we have a new minimum
if num_coins < min_coins:
min_coins = num_coins
# Reset the kNown result
kNown_results[target] = min_coins
return min_coins
这运行得很好,但是我对此几乎没有疑问。
我们为其输入以下内容以运行:
target = 74
coins = [1,5,10,25]
kNown_results = [0]*(target+1)
rec_coin_dynam(target,kNown_results)
为什么我们用长度为target + 1的零来激发已知结果?为什么我们不能只是写
kNow_results = []
解决方法
请注意,代码中包含以下行:
known_results[target] = 1
return known_results[target]
known_results[target] = min_coins
现在,让我演示python交互式shell中的[]
和[0]*something
之间的区别:
>>> a = []
>>> b = [0]*10
>>> a
[]
>>> b
[0,0]
>>>
>>> a[3] = 1
Traceback (most recent call last):
File "<stdin>",line 1,in <module>
IndexError: list assignment index out of range
>>>
>>> b[3] = 1
>>>
>>> a
[]
>>> b
[0,1,0]
引发了异常IndexError: list assignment index out of range
,因为我们试图访问列表a
的单元格3,但是a
的大小为0;没有单元格3。我们可以使用a
在a.append(1)
中输入一个值,但是1将位于位置0,而不是位置3。
当我们访问列表b
的单元格3时,也不例外,因为b
的大小为10,因此0到9之间的任何索引都是有效的。
结论:如果您预先知道数组的大小,并且该大小在算法执行过程中从未改变,那么您也可以从适当大小的数组开始,而不是使用空数组。
known_results
的大小是多少?该算法需要从0
到target
范围内的值的结果。那有多少结果?完全是target+1
。例如,如果target = 2
,则该算法将处理0、1和2的结果;那是3个不同的结果。因此known_results
的大小必须为target+1
。请注意,在python中,就像几乎所有其他编程语言一样,大小为n的列表包含n个元素,索引为0到n-1。通常,在整数间隔[a,b]中,存在b-a + 1个整数。例如,在间隔[8,10]中有三个整数(分别是8、9和10)。