给定一个数组,我发现子集的所有组合等于目标总和,因为我想要最大的数组。
例如,数组 [1,2,2,2] ,目标总和为" 4"返回 [[2,2],[2,2],[2,2]] 。
subsets = []
def subset_sum(numbers, target, partial=[]):
s = sum(partial)
if s == target:
subsets.append(partial)
if s >= target:
return
for i in range(len(numbers)):
n = numbers[i]
remaining = numbers[i + 1:]
subset_sum(remaining, target, partial + [n])
subsets.sort()
subsets.reversed()
如何删除子集中曾提到过的值'清单? 在上面的例子中,我怎么能只关注一个[2,2]。
那么,显示初始数组的值不在最终列表中? 在上面的例子中[1]。
答案 0 :(得分:0)
您可以使用itertools.groupby
删除重复的列表:
>>> import itertools
>>> lst = [[2, 2], [2, 2], [2, 2]]
>>> lst.sort()
>>> new_lst = list(k for k,_ in itertools.groupby(lst))
>>> print(new_lst)
[[2, 2]]
然后简单地用itertools.chain.from_iterable
展平new_lst
,并检查此展平列表中是否存在初始列表中的任何元素:
>>> initial = [1,2,2,2]
>>> print([x for x in initial if x not in itertools.chain.from_iterable(new_lst)])
[1]
注意:您可以让subset_sum()
返回非重复项目列表,但上述情况也可以正常工作。
答案 1 :(得分:0)
这不是您问题的直接答案,而是更好的算法。如果您只是查找满足您的总和标准的最大长度列表的一个示例,那么您应首先查看更长的列表。此代码使用itertools作为组合位,并在找到最长列表时停止。
numbers = [1, 2, 2, 2]
taget = 5
for size in reversed(range(1, 1 + len(numbers))):
for c in itertools.combinations(numbers, size):
if sum(c) == target:
break
else:
continue
break
c
现在包含最长的子集作为元组(1, 2, 2)
答案 2 :(得分:0)
您可以这样做:
数据是:
data=[1, 2, 2,2]
import itertools
your_target=4
一线解决方案:
print(set([k for k in itertools.combinations(data,r=2) if sum(k)==your_target]))
输出:
{(2, 2)}
或更好的使用函数:
def targeted_sum(data,your_target):
result=set([k for k in itertools.combinations(data,r=2) if sum(k)==your_target])
return result
print(targeted_sum(data,4))