面試題:用Python將一個數組分割成兩個數組,使兩個數組各自的和的差值最小

輸入一個任意長度的整形數組,輸出兩個數組,使得這兩個數組各自的和最接近。若是有多個解決方案,返回任意一個就行 [1,2,3,4,5] -> [1,2,5] & [3,4] [1,2,3,4,10] -> [1,2,3,4] & [10] [1,1,1,-1,-1,-1] -> [1,1,-1,-1] & [1,-1] 或者 [1,1,1,-1,-1,-1] & []。數組

解法1:多項式app

# Hello World program in Python
# coding=utf-8
import random

def test_input():
    arr = [-3000]
    for i in range(1000):
        n = random.randint(-10, 20)
        if n < 0:
            n -= 100
        elif n > 0:
            n += 100
        else:
            continue
        arr.append(n)
    return arr
arr = test_input()
# 求和
def sum(a):
    s = 0
    for i in a:
        s += i
    return s



# 分離數組
def split_array(arr):
    # 獲取數組並排序
    a = list(arr)
    #a.sort()
    # 另外一個數組

    b = list()
    # 以上a,b做爲待返回的數組

    # 計算數組大小
    n = len(a)#1000

    #求和
    smr = sum(a)

    # 和的一半,簡稱半和
    hs = smr / 2

    # 臨時和
    s = 0

   # 從最大的數字開始遍歷數組
    for i in range(-1,0-n,-1):
        # 預判該數字加和結果

        ns = s + a[i]
        if ns > hs:
            # 若是超出半和則跳過
            continue
        else:
            # 若是未超過半和,則:
            # 1, 取該元素加和
            s += a[i]
            # 2, 從 a 中將元素轉移到 b
            b.append(a[i])
            a.pop(i)
            # 若是最終和與半和之差,不夠最小元素,則完成
            if abs(s - hs) <= a[-1]:
                break
    return a, b

if __name__ == '__main__':
    # 測試:
    # [1,2,3,4,5] -> [1,2,5] & [3,4]
    # arr = test_input()
    print(split_array(arr))

解法2:揹包問題dom

# Hello World program in Python
# coding=utf-8
import random
import copy


def test_input():
    arr = [-300]
    for i in range(100):
        n = random.randint(-10, 20)
        if n < 0:
            n -= 100
        elif n > 0:
            n += 100
        else:
            continue
        arr.append(n)
    return arr


arr = test_input()


def incomplete_solution(arr):
    total = sum(arr)
    half = total / 2
    print(total, half)
    possibleSolution = {0: []}
    for i in arr:
        possibleSum = possibleSolution.keys()
        for k in possibleSum:
            now = i + k
            if (now not in possibleSum):
                valueList = possibleSolution[k]
                nowList = copy.copy(valueList)
                nowList.append(i)
                possibleSolution[now] = nowList
                if (now == half):
                    print("exactly match")
                    # print(nowList)
                    return nowList
    # now we can not found a perfect solution, so here to find the closest
    print(len(possibleSolution.keys()))
    # TODO... find the closest solution
    possibleSolution = {0: []}
    for i in arr:
        possibleSum = possibleSolution.keys()
        for k in possibleSum:
            now = i + k
            if (now not in possibleSum):
                valueList = possibleSolution[k]
                nowList = copy.copy(valueList)
                nowList.append(i)
                possibleSolution[now] = nowList
                if (now > half):
                    print("exactly match")
                    return nowList


if __name__ == '__main__':
    #arr = [1, 2, 3, 4, 233, 12, 123]  # test_input()
    n = incomplete_solution(arr)
    for i in n:
        arr.remove(i)
    print(n)
    print(sum(n))
    print(arr)
    print(sum(arr))
相關文章
相關標籤/搜索