Algorithm 这个问题需要一个算法

Algorithm 这个问题需要一个算法,algorithm,Algorithm,有两个长度为N的整数序列A[]和B[],均未排序 要求:通过A[]和B[]之间的元素交换(可以随机交换,不使用相同的索引),使{A[]}中所有元素的总和}和{B[]}中所有元素的总和}之间的差值最小 实际上,这是我遇到的一个面试问题 非常感谢试着贪婪一点。鉴于这些有限的信息,我不确定还有什么可以发表。这将是NP难的!我相信你可以从这个减少到这个 根据BlueRaja/polygene的评论,我将尝试从子集总和中提供一个完整的减少 这是一个减少: 子集和问题:给定整数x1,x2,…,xn,是否有一

有两个长度为N的整数序列A[]和B[],均未排序

要求:通过A[]和B[]之间的元素交换(可以随机交换,不使用相同的索引),使{A[]}中所有元素的总和}和{B[]}中所有元素的总和}之间的差值最小

实际上,这是我遇到的一个面试问题


非常感谢

试着贪婪一点。鉴于这些有限的信息,我不确定还有什么可以发表。

这将是NP难的!我相信你可以从这个减少到这个

根据BlueRaja/polygene的评论,我将尝试从子集总和中提供一个完整的减少

这是一个减少:

子集和问题:给定整数x1,x2,…,xn,是否有一些和为零的非空子集

我们的问题是:给定两个大小为k的整数数组,求两个数组之和的最小可能差,假设我们可以围绕数组中的整数进行洗牌,将两个数组视为一个数组

假设我们的问题有一个多项式时间算法

假设现在给你一个整数T={x1,x2,…,xn}(多重集)

设席=x1+x2+…+xn+X.

设Ti={x1,x2,…,xi-1,xi+1,…,xn}(=T-xi)

定义

Ai=使用Ti形成的阵列

Bi=[Si,0,…,0](即一个元素为Si,其余为零)

设mi=我们的问题为数组Ai和Bi找到的最小差值

(我们运行问题n次)

声明:T和的一些非空子集为零当且仅当存在一些i,其中mi=0

证明:(wlog)说x1+x2+…+xk=0

然后

A=[xk+1,…,xn,0,…,0]

B=[x2,x3,…,xk,S1,0,…]

给出最小差值m1为| x2+..+xk+(x1+…+xn)+x1-(xk+1+…+xn)|=| 2(x1+x2+…xk)|=0

同样,if部分也可以证明

事实上,这实际上也遵循(更容易)分区:只需创建包含所有零的新数组


毫无疑问,我没有犯任何错误。

以NP完全为例:

将正整数的多集a划分为两个具有相同和的多集B和C

像{a1,a2,…,an}。添加n个零{0,0,0…,0,a1,…,an},并询问是否可以将集合划分为两个具有相同总和和相同元素数的多集合A和B。我认为这两个条件是等价的:

  • 如果A和B是问题的解,那么你可以去掉零,得到partiton问题的解
  • 如果存在分区问题的解决方案,例如ai1+ai2+。。。aik=aj1++其中{ai1,ai2,aik,aj1,…,ajl}={a1,…,an}那么显然k+l=n。在左边加l个零,在右边加k个零,你会得到0+…+0+ai1+ai2+。。。aik=0+…+0+aj1++ajl,这是你问题的解决方案

所以,这是一个简化(所以问题是NP难的),而问题是NP,所以它是NP完全的。

我不确定这是否能保证最小可能的距离,但我想到的第一件事是这样的:

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;
        }

    }
int-diff=0;
对于(int i=0;i abs(diff+x)){
互换(a、b、i);
diff-=x;
}否则{
diff+=x;
}
}
假设您有一个交换函数,该函数接受两个数组并交换位置i处的项:)

计算并加上位置i处两个值之间的差值,即可得到两个数组元素之和之间的增量差值。
在每个步骤中,您检查是否最好添加(a[i]-b[i])或(b[i]-a[i])。如果b[i]-a[i]是这种情况,则交换阵列中位置i处的元素。


也许这不是最好的方法,但它应该是一个开始:)

这个问题是NP完全问题

我们可以将问题简化为决策版本,即给定两个相同大小的整数数组,确定是否可以交换项以使总和相等

分区问题的输入:一组大小为N的整数

为了将此输入转换为问题的输入,我们将A定义为S中所有项的数组,B定义为大小相同的数组,所有i的B[i]=0。此转换在输入大小上是线性的

很明显,我们在A和B上应用的算法,当且仅当S被划分为两个子集,使得总和相等时,才返回真值。

“长度为N的序列A[]和B[”->这是否意味着A和B都是长度为N的

(为了清晰起见,我在下面使用基于1的阵列)

如果是的话,这个怎么样:

  • 假设A[1..N]和B[1..N]

  • 将A和B连接到一个长度为2N:C[1..N]的新数组C中交换是否必须在每个序列的相同索引处进行?如果您想要任何严肃的答案,您确实需要添加更多细节。我们不是来为您做功课的。请在这一点上提供您对解决方案的想法。社区希望与您合作,而不是为您。@fbrereto:有人告诉我这个问题与NP完全相关,我对此感到困惑。这相当于将A和B的内容放在一个集合中,然后执行装箱,这是NP难的。@fatcat1111:您需要用另一种方式证明NP难。解决一个难题,并将其简化为当前问题。在这种情况下,子集和很容易减少到这个问题。@PolygeneLutories:我已经编辑了答案,指向有这个问题的wiki页面。这不是分区问题-在这种情况下,“一半”的大小是固定的。@BlueRaja,@PolygeneLutories:我已经编辑了帖子以显示减少的内容。是的,这是两个分区的分区问题,每个分区中必须有相同数量的元素。因此,它是NP完全的。@Justin:这不是