我被告知编写如下算法 存在三个相同大小N的数组A [],B [],C []。找出所有可能的(i,j,k),使得A [i] + B [j] = C [k]。允许的最大时间复杂度为O(N ^ 2)。以下是我为O(N ^ 2)编写的算法
#include<stdio.h>
#define MAX 1000
struct sum
{
int result;
int i;
int j;
};
int main()
{
struct sum sum_array[MAX];
int n=4;
int a[] = {4,1,2,5};
int b[] = {1,7,6,0};
int c[] = {11,3,8,2};
int k;
int i,j;
for(i=0;i<MAX;i++)
sum_array[i].result=-1;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
sum_array[a[i]+b[j]].result=a[i]+b[j];
sum_array[a[i]+b[j]].i=i;
sum_array[a[i]+b[j]].j=j;
}
}
for(k=0;k<n;k++)
{
if(sum_array[c[k]].result==c[k])
{
printf("<i,j,k> = <%d,%d,%d>\n",sum_array[c[k]].i,sum_array[c[k]].j,k);
}
}
return 0;
}
我的问题是如何更快地完成?任何O(N * logN)或更好的算法?
此致 ARKA
答案 0 :(得分:6)
最大答案大小为N ^ 3,因此无法实现更好的复杂性。 举个例子A = {1,1,1,1,1,1,1},B = {1,1,1,1,1,1} C = {2,2,2,2,2,2你接近的方法不会为上面的例子输出所有可能的三元组。
答案 1 :(得分:1)
如果您正在寻找一种组合或只是这些组合的数量,那么:
让MAX
成为数组A
,B
,C
的最大元素。
我的解决方案是O(MAX log(MAX))
。
我正在描述没有细节的想法。
让我们A_count[x]
=数组x
中的元素数量A
为A
,B
和C
计算此类数组
它可以在线性时间内完成。
将数组A_count
,B_count
和C_count
视为多项式。如果A[i] + B[j]
总和为X
,则A_count * B_count
(乘以多项式)为coefficient[X]
!= 0。
所以现在想法很简单。计算A_count * B_count
并将其系数与C_count
的系数进行比较。可以使用Discrete Fourier transform在A_count * B_count
中计算O(MAX log(MAX))
。
@edit,
上的例子int A[] = {4,1,2};
int B[] = {1,0};
int C[] = {3,8,2};
让我们计算A_count,B_count,C_count
0, 1, 2, 3, 4, 5, 6, 7, 8
int A_count[] = {0, 1, 1, 0, 1};
int B_count[] = {1, 1};
int C_count[] = {0, 0, 1, 1, 0, 0, 0, 0, 1}
现在让我们计算A_count * B_count。简单的乘法算法:
for(int i=0; i<A_count_SIZE; i++)
for(int j=0; j<B_count_SIZE; j++)
mult_result[i+j] += A_count[i] * B_count[j];
但可以更快地完成(Discrete Fourier transform)。
int mult_result[] = {0, 1, 2, 1, 1, 1}
这意味着:
1 pair sums to 1
2 pairs sums to 2
1 pair sums to 3
1 pair sums to 4
1 pair sums to 5
答案 2 :(得分:0)
我认为你找不到比O(N 2 )更快的东西,只是因为你必须遍历每个B的所有A来获得所有数组元素的总和。仅此一项是O(N 2 ),阻止你获得更快的任何东西。
编辑:虽然,有一些优化要做。例如,您设置了sum_array[a[i]+b[j]].result = a[i]+b[j]
。稍后您将测试密钥是否等于结果。它怎么可能是平等的呢?
答案 3 :(得分:0)
如果你想找到A[i]+B[j]=C[k]
的三元组(i,j,k)的存在,那么它可以在O(n^2 logn)
中完成。此外,您可以使用此方法找到此类三元组的数量。
D[]
,以便D
保存每对A
和B
的总和。这将使D = n ^ 2的大小。binary search
表示数组D
中C
的所有值。时间复杂度为O(n^2 logn)
。要计算三胞胎的数量,
仅当lower bound
中存在该值upper bound
时才能查找C[]
和D
中D
的值(可以使用下限函数返回的索引)。
count + = upper_bound_index - lower_bound_index;
时间复杂度也是O(n^2 logn)
。