问题描述
长度为 N 的可重复组合的总和是多少?
像 [1,3,5,10],N = 4。
还有
[1,1,1] -> sum is 4
[1,3] -> sum is 6
...
[10,10,10] -> sum is 40
我执行回溯算法。由 python3
res = set()
n = 4
def backtrack(k,path):
if len(path) == n:
res.add(sum(path))
return
backtrack(k+1,path+[1])
backtrack(k+1,path+[3])
backtrack(k+1,path+[5])
backtrack(k+1,path+[10])
return
backtrack(0,list())
有没有更有效的解决方案?
解决方法
如果 n elements
顺序不重要,那么你的代码是错误的
例如 [1,1,2,2] ~ [1,2]
您可以创建一个新列表并将原始列表的每个元素重复 n
次。那么问题是how many ways we can select n item from new list
,它可以很容易地计算出来
如果您想要所有 sums
的结果集,我认为没有比在所有情况下迭代更好的方法了。
O(n*len(list)*numberofdistinctsums)
方法。
我们有两组包含奇数步和偶数步的当前可能和。
我们根据前一步的总和(使用 i+1
个被加数)计算由 i
个被加数形成的新和。
例如,在两轮之后,我们有两个被加数的所有可能和。从前一个集合中获取和 8
,我们将三个被加数 8+1,8+3,8+5,8+10
的和放入新集合中,依此类推。
a = [1,3,5,10]
n = 4
sums = [set(a),set()]
for i in range(1,n):
sums[i%2].clear
for j in sums[(i+1)%2]:
for x in a:
sums[i%2].add(j + x)
print(len(sums[(n-1)%2]))