原文链接: https://leetcode-cn.com/problems/partition-array-into-two-arrays-to-minimize-sum-difference
英文原文
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:
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:
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 <= 15nums.length == 2 * n-107 <= nums[i] <= 107
中文题目
给你一个长度为 2 * n 的整数数组。你需要将 nums 分成 两个 长度为 n 的数组,分别求出两个数组的和,并 最小化 两个数组和之 差的绝对值 。nums 中每个元素都需要放入两个数组之一。
请你返回 最小 的数组和之差。
示例 1:

输入:nums = [3,9,7,3] 输出:2 解释:最优分组方案是分成 [3,9] 和 [7,3] 。 数组和之差的绝对值为 abs((3 + 9) - (7 + 3)) = 2 。
示例 2:
输入:nums = [-36,36] 输出:72 解释:最优分组方案是分成 [-36] 和 [36] 。 数组和之差的绝对值为 abs((-36) - (36)) = 72 。
示例 3:

输入:nums = [2,-1,0,4,-2,-9] 输出:0 解释:最优分组方案是分成 [2,4,-9] 和 [-1,0,-2] 。 数组和之差的绝对值为 abs((2 + 4 + -9) - (-1 + 0 + -2)) = 0 。
提示:
1 <= n <= 15nums.length == 2 * n-107 <= nums[i] <= 107
通过代码
高赞题解
两个数组和之差可以视作从 $\textit{nums}$ 中选 $n$ 个数取正号,其余 $n$ 个数取负号,然后求元素和。
我们可以使用折半枚举的方法,枚举 $\textit{nums}$ 的前 $n$ 个元素取正或取负的所有情况,按取正的个数分组,并按照元素和排序。然后枚举 $\textit{nums}$ 的后 $n$ 个元素取正或取负的所有情况,然后去对应的组里二分找元素和最近的数,答案即为所有情况中最小的差值。
相似题目:
func minimumDifference(nums []int) int {
n := len(nums) / 2
a := nums[:n]
res := make([][]int, n+1)
for i := 0; i < 1<<n; i++ {
sum, cnt := 0, 0
for j, v := range a {
if i>>j&1 > 0 { // 1 视作取正
sum += v
cnt++
} else { // 0 视作取负
sum -= v
}
}
res[cnt] = append(res[cnt], sum) // 按照取正的个数将元素和分组
}
for _, b := range res {
sort.Ints(b) // 排序,方便下面二分
}
ans := math.MaxInt64
a = nums[n:]
for i := 0; i < 1<<n; i++ {
sum, cnt := 0, 0
for j, v := range a {
if i>>j&1 > 0 {
sum += v
cnt++
} else {
sum -= v
}
}
// 在对应的组里二分最近的数
b := res[cnt]
j := sort.SearchInts(b, sum)
if j < len(b) {
ans = min(ans, b[j]-sum)
}
if j > 0 {
ans = min(ans, sum-b[j-1])
}
}
return ans
}
func min(a, b int) int {
if a > b {
return b
}
return a
}
统计信息
| 通过次数 | 提交次数 | AC比率 |
|---|---|---|
| 1939 | 6100 | 31.8% |
提交历史
| 提交时间 | 提交结果 | 执行时间 | 内存消耗 | 语言 |
|---|