我有4个A
,B
,C
,D
,大小为n
。 n
最多为4000.每个数组的元素是30位(正/负)数字。我想知道方法的数量,A[i]+B[j]+C[k]+D[l] = 0
可以形成0 <= i,j,k,l < n
。
我推导出的最佳算法是O(n^2 lg n)
,是否有更快的算法?
答案 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))