簡體   English   中英

給定一個整數列表,我如何檢查是否可以獲得 2 個相等和的子列表?

[英]Given a list of integers how do I check if it is possible to get 2 sublists of equal sum?

給定一個參數(整數列表),如果有可能得到兩個相等的子列表,則返回 True,否則返回 False。

我最初是先初始化 2 個子列表,然后開始將排序列表中的整數附加到總和較小的子列表中。

def split_ls(arr):
    arr.sort()
    a = []
    b = []
    while arr:
        push = arr.pop()
        if sum(a) == sum(b) or push == 0:
            a.append(push)
        elif sum(a) > sum(b):
            if push < 0:
                a.append(push)
            else:
                b.append(push)
        else:
            if push < 0:
                b.append(push)
            else:
                a.append(push)

    if sum(a) == sum(b):
        return True
    else:
        return False

這適用於某些測試用例,但不適用於所有測試用例... arr = [7, -3, 6, 1, 10, -4, 2, 2, 6, 7, -3, 2, 4, 0, 7 , 6, -2, 10, -4, 10]

這是分區問題的一個例子,它是 NP 難的。

一種相當“粗暴”的方法是嘗試 1、2... 的所有可能組合,最多為列表中值數量的一半,以找到一個加到總和一半的值。

在嘗試運行代碼之前估計此類組合的數量可能會很好。 我們最多需要測試長度為 n 的列表的子集數量的一半,因此 2^n / 2 = 2^(n-1)。

對於您的 20 個值列表,這將是 2^19 = 524288,這仍然可以在合理的時間內完成。

因此,我們可以嘗試使用itertools.combinations生成的組合,直到找到一個總和的一半,然后通過從原始列表中刪除我們找到的值來構建另一半列表:

from itertools import combinations 


def find_half_sum(arr):
    half_sum = sum(arr)/2

    for comb_size in range(1, len(arr)//2 + 1):
        for comb in combinations(arr, comb_size):
            if sum(comb) == half_sum:
                second = arr[:]
                for v in first:
                    second.remove(v)
                return(first, second)
            
    raise ValueError("Can't split this array in equal sums")
    
arr = [7, -3, 6, 1, 10, -4, 2, 2, 6, 7, -3, 2, 4, 0, 7, 6, -2, 10, -4, 10]
first, second = find_half_sum(arr)
    
print(first, sum(first))
print(second, sum(second))

#(6, 10, 6, 10) 32
#[7, -3, 1, -4, 2, 2, 7, -3, 2, 4, 0, 7, 6, -2, -4, 10] 32

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM