Problem Link

Description


You are given an integer array nums of 2 * n integers. You need to partition nums into two arrays of length n to minimize the absolute difference of the sums of the arrays. To partition nums, put each element of nums into one of the two arrays.

Return the minimum possible absolute difference.

Β 

Example 1:

example-1
Input: nums = [3,9,7,3]
Output: 2
Explanation: One optimal partition is: [3,9] and [7,3].
The absolute difference between the sums of the arrays is abs((3 + 9) - (7 + 3)) = 2.

Example 2:

Input: nums = [-36,36]
Output: 72
Explanation: One optimal partition is: [-36] and [36].
The absolute difference between the sums of the arrays is abs((-36) - (36)) = 72.

Example 3:

example-3
Input: nums = [2,-1,0,4,-2,-9]
Output: 0
Explanation: One optimal partition is: [2,4,-9] and [-1,0,-2].
The absolute difference between the sums of the arrays is abs((2 + 4 + -9) - (-1 + 0 + -2)) = 0.

Β 

Constraints:

  • 1 <= n <= 15
  • nums.length == 2 * n
  • -107 <= nums[i] <= 107

Solution


Python3

class Solution:
    def minimumDifference(self, nums: List[int]) -> int:
        
        def construct(A):
            n = len(A)
            mp = {}
            
            for k in range(1, n + 1):
                sums = []
                for comb in combinations(A, k):
                    sums.append(sum(comb))
                mp[k] = sums
            
            return mp
        
        n = len(nums) // 2
        left, right = nums[:n], nums[n:]
        left_part, right_part = construct(left), construct(right)
        res = abs(sum(left) - sum(right))
        total = sum(nums)
        half = total // 2
        
        for k in range(1, n - 1):
            l, r = left_part[k], right_part[n - k]
            r.sort()
            
            for x in l:
                target = half - x
                index = bisect.bisect_left(r, target)
                
                for p in (index - 1, index):
                    if 0 <= p < len(r):
                        leftSum = x + r[p]
                        rightSum = total - leftSum
                        res = min(res, abs(leftSum - rightSum))
            
        return res