我试图编写代码以递归方式检查列表是否可以划分为具有相同总和的两个子列表,因此需要传递列表的所有组合,例如:[1,2,3,4]所以我需要检查:
1 ------ 2,3,4-
1,2- ------ 3,4
1,3 ------ 2,4
等...... 但是我找不到怎么做的方法。
答案 0 :(得分:1)
递归检查列表是否可以划分为具有相同总和的两个子列表
您可以使用递归轻松实现greedy partition algorithm:
def _greedy_part(r, sa, la, sb, lb):
if not r:
return sa == sb, la, lb;
if sb < sa:
# swap both lists in order to always have
# the "lower sum list" as sa/la
sb, sa = sa, sb
lb, la = la, lb
return _greedy_part(r[1:], sa+r[0], la+r[0:1], sb, lb)
def greedy_part(r):
return _greedy_part(sorted(r,reverse=True), 0, [], 0, [])
关键的想法是始终将最大的剩余价值添加到具有最低总和的列表中。再一次,该解决方案在Python中表现不佳,因为函数调用效率不高,Python没有tail call optimization。
鉴于样本测试:
print(greedy_part([1,2,3,4]))
print(greedy_part([1,2,3,4,5]))
print(greedy_part([6,1,2,3]))
它会产生:
(True, [4, 1], [3, 2])
(False, [5, 2, 1], [4, 3])
(True, [3, 2, 1], [6])
答案 1 :(得分:0)
蛮力:
import itertools
seq = [1, 2, 3, 4]
S = sum(seq)
for i in xrange(1, len(seq)):
for c in itertools.combinations(seq, i):
print c, 2*sum(c) == S
这是不解决问题的最有效方法。阅读:http://en.wikipedia.org/wiki/Partition_problem
答案 2 :(得分:0)
您可以使用
simleo建议的itertools。这是强力解决方案,将在指数时间内运行。
使用{(3}}给出的传统子集问题解决方案(total_sum_of_nums)* len(list)time