这是一个采访问题。
“给定一个排序的数组。找出具有相同差异的夫妻数量。”
例如:if array是{1,2,3,5,7,7,8,9};
然后我们
5对,差异为1
6对,差异为2
4对,差异为4
2对,差异为3
4对,差异为6
3对,差异为5
2对,差异为7
1对,差异为8
1对,差异为0
我尝试了以下内容:
maxdiff=arr[n-1]-arr[0]; //calculating the maximum difference
int b[maxdiff];
for(i=0;i<maxdiff;i++)
{
for(j=0;j<n;j++)
{
p=arr[j]+i;
x=binarysearch(p,arr); //search p in array,where x return 0/1
if(x==1)
b[i]++;
}
}
这是O(k * n * logn)解决方案,其中k是排序数组的第一个和最后一个元素之间的最大差异,n是数组大小。
有没有人有比这更好的想法?
答案 0 :(得分:7)
这似乎不必要地复杂,我不完全明白你在做什么。问题是否仅通过以下方式解决:
maxdiff=arr[n-1]-arr[0]; //calculating the maximum difference
int b[maxdiff];
for(i=0;i<n;i++)
{
for(j=0;j<i;j++) // note: <i instead of <n
{
b[arr[i]-arr[j]]++
}
}
这是O(n ** 2)。
顺便说一下,你没有列出差异为8的一对或者差异为0的一对。有意吗?编辑:
逻辑就是:查看原始数组中的每一对。每对形成差异。为这种差异增加计数器。
编辑2:
根据您的要求,以下是我的测试结果:
C:\src>a
diff: 0 pairs: 1
diff: 1 pairs: 5
diff: 2 pairs: 6
diff: 3 pairs: 2
diff: 4 pairs: 4
diff: 5 pairs: 3
diff: 6 pairs: 4
diff: 7 pairs: 2
diff: 8 pairs: 1
以及完整的计划:
#include <iostream>
using namespace std;
int main (int argc, char *argv[])
{
int n=8;
int arr[] = {1,2,3,5,7,7,8,9};
int i, j;
int maxdiff=arr[n-1]-arr[0]; //calculating the maximum difference
int b[maxdiff];
for(i=0;i<=maxdiff;i++)
{
b[i]=0;
}
for(i=0;i<n;i++)
{
for(j=0;j<i;j++) // note: <i instead of <n
{
b[arr[i]-arr[j]]++;
}
}
for (i=0;i<=maxdiff;++i)
cout<<"diff: "<<i<<" pairs: "<<b[i]<<endl;
}
答案 1 :(得分:5)
如果使用Fourier transform进行多项式的乘法,这可以用O(k * log k)求解(其中k是最大差值)。
考虑以下问题:有两组A = a_1,...,a_n和B = b_1,...,b_m,对于每个X找到对的数量(i,j),使得a_i + b_j = X.可以解决如下。
设Pa = x ** a_1 + ... + x ** a_n,Pb = x ** b_1 + ... + x ** b_m。如果你看一下Pa * Pb,你可能会发现x ** R的系数是X = R问题的答案。所以,使用傅立叶变换乘以这个多项式,你会发现O中每个X的答案。 (n * log n)。
之后,你的问题可能会减少到这个问题,说A = arr_1,...,arr_n,B = -arr_1,...,-arr_n和移位(加一个常数)到A和B的每个值让它们介于0和k之间。
答案 2 :(得分:1)
对于一般输入数组,这不能比O(n ^ 2)更好地解决,因为一些输入导致O(n ^ 2)个不同的输出。例如,很容易构造一个数组,其中每对元素具有不同的分离。
如果要求具有某些指定分离的对的数量,问题会更有意义。这可以在线性时间内完成,并使用数组排序的事实。如果我们能做的最好的事情比排序慢,那么给出一个排序的数组真的没有意义。