当每个块的总和大致相等时,如何将数组拆分成两个块?
>>> foo([10, 1, 1, 1])
[[10], [1, 1, 1]]
>>> foo([2, 5, 9, 5, 1, 1])
[[2, 5], [9, 5, 1, 1]]
>>> foo([9, 5, 5, 8, 2, 2, 18, 8, 3, 9, 4])
[[9, 5, 5, 8, 2, 2], [18, 8, 3, 9, 4]]
>>> foo([17, 15, 2, 18, 7, 20, 3, 20, 12, 7])
[[17, 15, 2, 18, 7], [20, 3, 20, 12, 7]]
>>> foo([19, 8, 9, 1, 14, 1, 16, 4, 15, 5])
[[19, 8, 9, 1], [14, 1, 16, 4, 15, 5]]
答案 0 :(得分:2)
类似的东西:
def foo(lst):
total_sum = sum(lst)
i = 1
while sum(lst[:i]) < total_sum / 2: # iterate over the list slices until we hit the "middle"
if sum(lst[:i+1]) >= total_sum / 2: # also make sure that we won't go further
break
i += 1
return [lst[:i], lst[i:]]
测试:
[[10], [1, 1, 1]] # 10 + 3
[[2, 5], [9, 5, 1, 1]] # 7 + 16
[[9, 5, 5, 8, 2, 2], [18, 8, 3, 9, 4]] # 31 + 42
[[17, 15, 2, 18, 7], [20, 3, 20, 12, 7]] # 59 + 62
[[19, 8, 9, 1], [14, 1, 16, 4, 15, 5]] # 37 + 55
答案 1 :(得分:2)
您可以在列表上创建包含循环的切片,然后使用正确的密钥选择具有min
功能的正确对:
>>> def find_min(l):
... return min(((l[:i],l[i:]) for i in range(len(l))),key=lambda x:abs((sum(x[0])-sum(x[1]))))
演示:
>>> l=[10, 1, 1, 1]
>>> find_min(l)
([10], [1, 1, 1])
>>> l=[9, 5, 5, 8, 2, 2, 18, 8, 3, 9, 4]
>>> find_min(l)
([9, 5, 5, 8, 2, 2], [18, 8, 3, 9, 4])
>>> l=[19, 8, 9, 1, 14, 1, 16, 4, 15, 5]
>>> find_min(l)
([19, 8, 9, 1, 14], [1, 16, 4, 15, 5])
答案 2 :(得分:1)
假设当列表在列表的累积总和尽可能接近整个列表总和的一半时被分区时,获得最佳分割:
import numpy as np
x = [19, 8, 9, 1, 14, 1, 16, 4, 15, 5]
csum = np.cumsum(x)
ix = np.argmin(abs(csum-csum[-1]/2)) + 1
result = [x[:ix], x[ix:]]
结果:
[[19, 8, 9, 1, 14], [1, 16, 4, 15, 5]]
答案 3 :(得分:0)
这是我的解决方案:
def sum(*args):
total = 0
if len(args) > 0:
for i in args:
for element in i:
total += element
return total
def foo(Input):
size = len(Input)
checkLeftCross = 0
previousLeft = 0
previousRight = 0
currentLeft = 0
currentRight = 0
targetIndex = 0
for i in range(size):
currentLeft = sum(Input[0:i])
currentRight = sum(Input[i:size])
if currentLeft >= currentRight:
targetIndex = i
break
else:
previousLeft = currentLeft
previousRight = currentRight
diffPrev = previousRight - previousLeft
diffCurr = currentLeft - currentRight
if diffPrev > diffCurr:
return Input[0:targetIndex], Input[targetIndex:size]
else:
return Input[0:targetIndex-1], Input[targetIndex-1:size]
def main():
print foo([2, 5, 9, 5, 1, 1])
print foo([10,1,1,1])
print foo([9, 5, 5, 8, 2, 2, 18, 8, 3, 9, 4])
print foo([17, 15, 2, 18, 7, 20, 3, 20, 12, 7])
print foo([19, 8, 9, 1, 14, 1, 16, 4, 15, 5])
if __name__ == "__main__":
main()
说明:
sum
来返回列表中所有元素的总和。输出:
([2, 5], [9, 5, 1, 1])
([10], [1, 1, 1])
([9, 5, 5, 8, 2, 2], [18, 8, 3, 9, 4])
([17, 15, 2, 18, 7], [20, 3, 20, 12, 7])
([19, 8, 9, 1, 14], [1, 16, 4, 15, 5])
答案 4 :(得分:0)
from itertools import combinations
from collections import Counter
def most_equal_pairs(seq, n=None):
seq_mapping = dict(enumerate(seq))
if len(seq_mapping) < 2:
raise ValueError()
if len(seq_mapping) == 2:
first, second = seq_mapping.values()
yield [first], [second], abs(first - second)
return
ids = set(seq_mapping)
def get_chunk_by_ids(ids):
return [seq_mapping[i] for i in ids]
def get_chunk_sum_by_ids(ids):
return sum(get_chunk_by_ids(ids))
pairs = Counter()
for comb_len in range(1, len(ids) - 1):
for first_comb in combinations(ids, comb_len):
second_comb = tuple(ids - set(first_comb))
first_sum = get_chunk_sum_by_ids(first_comb)
second_sum = get_chunk_sum_by_ids(second_comb)
diff = abs(first_sum - second_sum)
pairs[(first_comb, second_comb)] = -diff
for (first_comb_ids, second_comb_ids), diff in pairs.most_common(n):
first_comb = get_chunk_by_ids(first_comb_ids)
second_comb = get_chunk_by_ids(second_comb_ids)
yield first_comb, second_comb, abs(diff)
def test(seq):
pairs = list(most_equal_pairs(seq))
diff_seq = []
for first, second, diff in pairs:
assert abs(sum(first) - sum(second)) == abs(diff)
diff_seq.append(diff)
assert tuple(sorted(diff_seq)) == tuple(diff_seq)
best_pair = pairs[0]
first, second, diff = best_pair
return first, second, sum(first), sum(second), diff
结果
>>> test([10, 1, 1, 1])
([10], [1, 1, 1], 10, 3, 7)
>>> test([2, 5, 9, 5, 1, 1])
([2, 9, 1], [5, 5, 1], 12, 11, 1)
>>> test([9, 5, 5, 8, 2, 2, 18, 8, 3, 9, 4])
([5, 8, 2, 2, 8, 3, 9], [9, 5, 4, 18], 37, 36, 1)
>>> test([17, 15, 2, 18, 7, 20, 3, 20, 12, 7])
([18, 3, 20, 12, 7], [17, 15, 2, 7, 20], 60, 61, 1)
>>> test([19, 8, 9, 1, 14, 1, 16, 4, 15, 5])
([19, 9, 14, 4], [8, 1, 1, 16, 15, 5], 46, 46, 0)