我想获得可能的子集,例如:input是{1,2,3}
预期结果:
1
2
3
1,2
1,3
1,2,3
2,3
我使用递归来实现它,它认为它很慢,它有更有效的方法吗?
答案 0 :(得分:1)
您可以考虑一种递归方法:
PSEUDO CODE:
allsums = makeAllSums(setOfNumbers){
if(1==setOfNumbers.size)
return setOfNumbers.head
result = emptySet
for(a in setOfNumbers)
allSubSums=makeAllSums(setOfNumbers without a);
for(b in allSubSums)
result.add(a."+".b)
return result
}
你只需要考虑避免重复。
答案 1 :(得分:1)
这是subset sum problem的变体,可以使用Dynamic Programming在O(n*SUM)
中解决,其中SUM
是所有数字的总和。
D(i,x) = D(i-1,x) OR D(i-1,x-arr[i])
D(0,0) = true
D(0,x) = false x != 0
在此处,D(i,x)
给出一个布尔值,指示是否可以使用部分或全部x
第一个元素来达到总和i
。因此,对于每个可能的总和x
,D(n,x)
表示是否可以使用任何数字达到此总和。
答案 2 :(得分:0)
基于要添加到总和的元素的二进制数表示的想法
从最初的集合。
1 2 3 4 5 6 7 9 10
每个可能的总和可以写成8位二进制数字,其中每个数字代表'取这个总和'不要把这个用在总和中。
示例:
001010100 means 3+5+7
111111111 means 1+2+3+4+5+6+7+9+10
000000001 means 10
010000000 means 2
因此,每个可能的总和可以写成长度为9的0和1的序列。
所有总和都是长度为9的可能序列。
所以你可以简单地循环数字1到2 ^ 9-1并将二进制表示解释为总和。
000000001 : 10
000000010 : 9
000000011 : 9 + 10
000000100 : 7
000000101 : 7 + 10
...
111111111 : 1+2+3+4+5+6+7+9+10
这样你就得到了所有的金额(没有重复)