【发布时间】:2018-04-25 18:26:30
【问题描述】:
我有以下作业:给定一个包含 n 个整数的列表,列表中的每个整数都是唯一的并且大于 0。我还得到了一个数字 K——它是一个大于 0 的整数。 不允许任何形式的列表切片
我需要检查是否存在总和为 K 的子集。 例如:对于列表 [1,4,8] 和 k=5,我返回 True,因为我们有子集 {1,4}。
现在我需要使用递归来实现它: 所以我做了,但是我需要实现记忆:
我想知道这些函数的代码有什么区别: 我的意思是,两者似乎都实现了记忆,但是第二个应该更好,但事实并非如此。我真的很感激一些帮助:)
def subsetsum_mem(L, k):
'''
fill-in your code below here according to the instructions
'''
sum_dict={}
return s_rec_mem(L,0,k,sum_dict)
def s_rec_mem(L, i, k, d):
'''
fill-in your code below here according to the instructions
'''
if(k==0):
return True
elif(k<0 or i==len(L)):
return False
else:
if k not in d:
res_k=s_rec_mem(L,i+1,k-L[i],d) or s_rec_mem(L,i+1,k,d)
d[k]=res_k
return res_k
def subsetsum_mem2(L, k):
'''
fill-in your code below here according to the instructions
'''
sum_dict={}
return s_rec_mem2(L,0,k,sum_dict)
def s_rec_mem2(L, i, k, d):
'''
fill-in your code below here according to the instructions
'''
if(k==0):
return True
elif(k<0 or i==len(L)):
return False
else:
if k not in d:
res_k=s_rec_mem2(L,i+1,k-L[i],d) or s_rec_mem2(L,i+1,k,d)
d[k]=res_k
return res_k
else:
return d[k]
【问题讨论】:
-
在第一个中,如果
k在d中,你永远不会返回任何东西 -
“工作得更好”是什么意思?
-
第一个没有做正确的事情,因为如果值已经在缓存中,它会从末尾掉下来并返回
None而不是d[k]。由于None是错误的,这很可能使您的代码运行得更快,只需不做大部分必要的工作并很快返回错误的答案。 -
顺便说一下,您可能想看看使用
@functools.lru_cache进行记忆。即使您正在编写自己的 memoization 作为学习练习(或试图超越lru_cache... 的性能),也值得拥有经过良好测试的标准实现,以便在单元测试和基准测试中比较您的版本。跨度> -
@abarnert 哦,我明白了,那么第一个返回一些 None 值可能会使代码运行得更快,但实际上并不起作用。所以问题是,第二个代码是否真的让这个过程更有效率?还是我错过了什么? abarnert - 关于 Iru_cache,我会调查一下,谢谢 :)
标签: python recursion memoization