原文链接: 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 <= 15
nums.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 <= 15
nums.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% |
提交历史
提交时间 | 提交结果 | 执行时间 | 内存消耗 | 语言 |
---|