从4组求和0的算法

时间:2011-09-26 10:42:19

标签: algorithm

我有4个ABCD,大小为nn最多为4000.每个数组的元素是30位(正/负)数字。我想知道方法的数量,A[i]+B[j]+C[k]+D[l] = 0可以形成0 <= i,j,k,l < n

我推导出的最佳算法是O(n^2 lg n),是否有更快的算法?

3 个答案:

答案 0 :(得分:4)

好的,这是我的O(n ^ 2lg(n ^ 2))算法 -

假设有四个数组A [],B [],C [],D []。我们希望找到A [i] + B [j] + C [k] + D [1] = 0的路数,其中0 <= i,j,k,l <0。 ñ。

因此,总结A []和B []的所有可能排列,并将它们放在另一个包含n * n个元素的数组E []中。

int k=0;
for(i=0;i<n;i++)
{
    for(j=0;j<n;j++)
    {

        E[k++]=A[i]+B[j];


    }
}
  

上述代码的复杂性为O(n ^ 2)。

为C []和D []执行相同的操作。

int l=0;

for(i=0;i<n;i++)
{
     for(j=0;j<n;j++)
     {

          AUX[l++]=C[i]+D[j];

     }
}
  

上述代码的复杂性为O(n ^ 2)。

现在对AUX []进行排序,以便您可以轻松找到AUX []中唯一元素的出现次数。

  

AUX []的排序复杂度为O(n ^ 2 lg(n ^ 2))。

现在声明一个结构 -

struct myHash
{
  int value;
  int valueOccuredNumberOfTimes; 

}F[];

现在在结构F []中放置AUX []的唯一元素和它们出现的时间。

  

它的复杂性是O(n ^ 2)

possibleQuardtupple=0;

现在对于E []的每个项目,请执行以下操作

for(i=0;i<k;i++)
 {

     x=E[i];

     find -x in structure F[] using binary search.
     if(found in j'th position)
     {
        possibleQuardtupple+=number of occurrences of -x in F[j];

     }      
 }
  

对于循环i,执行总共n ^ 2个迭代次数并在每个循环中执行   用于二进制搜索的迭代lg(n ^ 2)比较完成。总的来说   复杂度为O(n ^ 2 lg(n ^ 2))。

可以达到0的路数是= possibleQuardtupple。

现在您可以使用stl map / binary搜索。但是stl map很慢,所以最好使用二进制搜索。

希望我的解释清楚明白。

答案 1 :(得分:-1)

我不同意你的解决方案实际上和你说的一样有效。在您的解决方案中,填充E []和AUX []各自为O(N ^ 2),因此2.N ^ 2。这些将具有N ^ 2个元素。

生成x = O(N)

排序AUX = O((2N)* log((2N)))

AUX []中E [i]的二分搜索基于N ^ 2个元素中的N ^ 2个元素。

因此,您仍在进行N ^ 4工作,以及生成中间数组ans的额外工作,用于对AUX []中的N ^ 2个元素进行排序。

我有一个解决方案(正在进行中),但我发现计算它的工作量非常困难。我删除了以前的答案。当我对自己更加肯定时,我会发布一些东西。

我需要找到一种比较O(X)+ O(Z)+ O(X ^ 3)+ O(X ^ 2)+ O(Z ^ 3)+ O(Z ^ 2)+ X的方法.log(X)+ Z.log(Z)到O(N ^ 4),其中X + Z = N.

显然小于O(N ^ 4)......但是多少????我的数学在这里让我失望....

答案 2 :(得分:-1)

判断错了。提供的解决方案生成大小为N ^ 2的阵列。然后它在这些数组上运行(排序等)。

因此,工作顺序(通常为O(n ^ 2.log(n))应该用n ^ 2代替。因此结果是O((n ^ 2)^ 2.log(n ^ 2))