Leetcode: 2035. Partition Array Into Two Arrays to Minimize Sum Difference

Problem Statement

from typing import List
from bisect import bisect_left


class Solution:
    def minimumDifference(self, nums: List[int]) -> int:
        N = len(nums)
        M = N // 2

        m = min(n for n in nums)
        nums = [m + n for n in nums]
        S = sum(nums)

        a = [set() for _ in range(M + 1)]
        b = [set() for _ in range(M + 1)]

        a[0].add(0)
        b[0].add(0)

        for n in nums[:M]:
            for i in range(M - 1, -1, -1):
                for k in a[i]:
                    a[i + 1].add(k + n)

        for n in nums[M:]:
            for i in range(M - 1, -1, -1):
                for k in b[i]:
                    b[i + 1].add(k + n)

        for i in range(M + 1):
            a[i] = sorted(a[i])
            b[i] = sorted(b[i])

        ans = float("inf")
        for i in range(M + 1):
            j = M - i
            for p in a[i]:
                t = S // 2 - p
                m = bisect_left(b[j], t)
                for k in range(max(0, m - 1), min(m + 1, len(b[j]))):
                    ans = min(ans, abs(S - 2 * (p + b[j][k])))

        return ans


assert Solution().minimumDifference([3, 9, 7, 3]) == 2
assert Solution().minimumDifference([-36, 36]) == 72
assert Solution().minimumDifference([2, -1, 0, 4, -2, -9]) == 0