面试题:用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:多项式

# 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:背包问题

# 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))

猜你喜欢

转载自my.oschina.net/u/3764483/blog/1820160
今日推荐