加载中...
2035-将数组分成两个数组并最小化数组和的差(Partition Array Into Two Arrays to Minimize Sum Difference)
发表于:2021-12-03 | 分类: 困难
字数统计: 874 | 阅读时长: 4分钟 | 阅读量:

原文链接: 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:

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

中文题目

给你一个长度为 2 * n 的整数数组。你需要将 nums 分成 两个 长度为 n 的数组,分别求出两个数组的和,并 最小化 两个数组和之 差的绝对值 。nums 中每个元素都需要放入两个数组之一。

请你返回 最小 的数组和之差。

 

示例 1:

example-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:

example-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%

提交历史

提交时间 提交结果 执行时间 内存消耗 语言
上一篇:
2034-股票价格波动(Stock Price Fluctuation )
下一篇:
2053-数组中第 K 个独一无二的字符串(Kth Distinct String in an Array)
本文目录
本文目录