有两个长度为N的整数序列A []和B [],都是未排序的。
要求:通过交换A []和B []之间的元素(可以随机交换,而不是使用相同的索引),区分{A []}中所有元素的总和与{所有元素的总和B []}中的元素最小。
PS:实际上,这是我遇到的面试问题。非常感谢
答案 0 :(得分:6)
这将是NP难!我相信你可以从Subset Sum减少到此。
根据BlueRaja / polygene的评论,我将尝试提供Subset Sum的完全减少。 击>
这是一个减少:
子集和问题:给定整数x 1 ,x 2 ,...,x n ,是否有一些非空子集总和为零?
我们的问题:给定两个大小为k的整数数组,找到两个数组之和的最小可能差异,假设我们可以在数组中整数排列,将两个数组视为一个数组。
假设我们的问题有多项式时间算法。
现在说你得到整数T = {x 1 ,x 2 ,...,x n }(multiset)< / p>
设S i = x 1 + x 2 + ... + x n + x <子> I 子>
设T i = {x 1 ,x 2 ,...,x i-1 ,x i + 1 ,...,x n }(= T - x i )
定义
i =使用T i
形成的数组B i = [S i ,0,...,0](即一个元素是S i ,其余为零)。
设m i =我们的问题找到的数组A i 和B i
的最小差异(我们运行我们的问题n次)。
声明:当且仅当有一些i时,T的一些非空子集合为零,其中m i = 0。
证明:(wlog)说x 1 + x 2 + .. + x k = 0
然后
A = [x k + 1 ,...,x n ,0,... 0]
B = [x 2 ,x 3 ,...,x k ,S 1 , 0,.0]
给出最小差值m 1 为| x 2 + .. + x k +(x 1 + ... + x n )+ x 1 - (x k + 1 + .. + x n < /子>)| = | 2(x 1 + x 2 + .. x k )| = 0。
同样可以证明if部分。
实际上,这实际上也跟随(更容易)来自分区:只需创建全零的新数组。
我没有犯任何错误。
答案 1 :(得分:3)
采取NP-complete的任何实例partition problem:
将一个正整数的多重A分成两个具有相同和的多重集B和C
喜欢{a 1 , 2 ,..., n }。添加n个零{0,0,0 ...,0,一个 1 ,...,一个 n }并询问该集合是否可以划分为两个多重集合A和B具有相同的总和和相同数量的元素。我声称这两个条件是等价的:
所以,这是一个减少(所以问题是NP难),问题是NP,所以它是NP完全的。
答案 2 :(得分:2)
“长度为N”的序列A []和B [] - >这是否意味着A和B都每个长度为N?
(为了清楚起见,我在下面使用基于1的数组)。
如果是这样,那怎么样:
这里的观察是,在排序的数组中,相邻的一对数字将具有最小的差异(与来自非相邻位置的一对数字相比)。步骤3确保A [1]和B [1]由一对具有最小可能差异的数字组成。步骤4确保(a)A [2]和B [2]由一对具有最小可能差异的数字(来自可用数字)组成,并且(b)差异与步骤3中的符号相反。像这样继续,我们确保A [i]和B [i]包含差异最小的数字。此外,通过翻转我们将元素发送到A和B的顺序,我们确保每个连续的i的差异发生变化。
答案 3 :(得分:1)
试着对它贪婪。鉴于这些有限的信息,我不确定那里还有什么可以推出。
答案 4 :(得分:0)
我不确定这是否会确保最小可能距离,但首先要考虑的是这样的事情:
int diff=0;
for (int i = 0; i<len; i++){
int x = a[i] - b[i];
if (abs(diff - x) > abs(diff + x)){
swap(a,b,i);
diff-=x;
}else{
diff+=x;
}
}
假设您有一个交换函数,它接受两个数组并交换位置i处的项目:)
计算并添加位置i处两个值之间的差值,可以得到两个数组之和的增量差值。
在每一步,你检查是否更好地添加(a [i] -b [i])或(b [i] -a [i])。如果b [i] -a [i]就是这种情况,你可以交换数组中位置i的元素
也许这不是最好的方式,但它应该是一个开始:)
答案 5 :(得分:0)
问题是NP-Complete。
我们可以将此问题的partition problem减少到决策版,即给定两个相同大小的整数数组,确定是否可以交换项目以使总和相等
分区问题的输入:整数S,大小为N
为了将此输入转换为我们问题的输入,我们将A定义为S中所有项的数组,B定义相同大小的数组,对于所有i,B [i] = 0。此转换在输入大小上是线性的。
很明显,当且仅当S分区为2个子集以使得总和相等时,我们在A和B上应用的算法才返回true。