Skip to content

2035. Partition Array Into Two Arrays to Minimize Sum Difference

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

 

Solutions

Solution: Depth-First Search + Binary Search

  • Time complexity: O(n*2n)
  • Space complexity: O(2n)

 

JavaScript

js
/**
 * @param {number[]} nums
 * @return {number}
 */
const minimumDifference = function (nums) {
  const n = nums.length / 2;
  const sum = nums.reduce((result, num) => result + num);
  const goal = sum / 2;
  const leftNums = nums.slice(0, n);
  const rightNums = nums.slice(n);
  const leftSums = Array.from({ length: n + 1 }, () => []);
  const rightSums = Array.from({ length: n + 1 }, () => []);
  let result = Number.MAX_SAFE_INTEGER;

  const dfsSums = (nums, index, count, sum, sums) => {
    if (index >= n) {
      sums[count].push(sum);
      return;
    }

    const num = nums[index];

    dfsSums(nums, index + 1, count, sum, sums);
    dfsSums(nums, index + 1, count + 1, sum + num, sums);
  };

  dfsSums(leftNums, 0, 0, 0, leftSums);
  dfsSums(rightNums, 0, 0, 0, rightSums);

  const findFirstGreaterEqual = (nums, target) => {
    let left = 0;
    let right = nums.length - 1;

    while (left <= right) {
      const mid = Math.floor((left + right) / 2);

      nums[mid] >= target ? (right = mid - 1) : (left = mid + 1);
    }

    return left;
  };

  for (let leftCount = 0; leftCount <= n; leftCount++) {
    const lSums = leftSums[leftCount];
    const rSums = rightSums[n - leftCount];

    rSums.sort((a, b) => a - b);

    for (const leftSum of lSums) {
      const index = findFirstGreaterEqual(rSums, goal - leftSum);

      if (index < rSums.length) {
        const sum1 = leftSum + rSums[index];
        const sum2 = sum - sum1;

        result = Math.min(Math.abs(sum1 - sum2), result);
      }

      if (index > 0) {
        const sum1 = leftSum + rSums[index - 1];
        const sum2 = sum - sum1;

        result = Math.min(Math.abs(sum1 - sum2), result);
      }
    }
  }

  return result;
};

Released under the MIT license