计算相同对的数量

时间:2015-04-09 13:03:16

标签: algorithm sorting

数组中的相同对是2个索引p,q,这样

0<=p<q<Narray[p]=array[q]其中N是数组的长度。

给定一个未排序的数组,找到数组中相同的数字对。

我的解决方案是按值对数组进行排序, 跟踪指数。

然后对于排序数组中的每个索引p,计算所有q<N以及

sortedarray[p].index < sortedarray[q].index and 
sortedarray[p] = sortedarray[q]  

这是正确的做法吗?我认为复杂性将是

O(N log N) for sorting based on value  +

O(N^2) for counting the newsorted array that satisfies the condition. 

这意味着我仍在关注O(N^2)。还有更好的方法吗?

另一个想法是每个P二进制搜索满足条件的所有Q的排序数组。这不会将第二部分的复杂性降低到O(Nlog(N))

这是我的第二部分代码

    for(int i=0;i<N;i++){

                    int j=i+1;

            while( j<N && sortedArray[j].index > sortedArray[i].index &&
                   sortedArray[j].item == sortedArray[i].item){

                        inversion++;
                        j++;
            }
      }
   return inversion;

@Edit:我想,我把第二部分的复杂性误认为是O(N^2)

与while循环中的每次迭代一样,不会发生索引0-i中元素的重新扫描,扫描排序后的数组以计算反转需要线性时间。因此总复杂度

O(NlogN)用于排序,O(N)用于排序数组中的线性扫描计数。

4 个答案:

答案 0 :(得分:3)

你是部分正确的。通过Merge Sort或Heapsort对数组进行排序将需要O(n lg n)。但是一旦对数组进行了排序,您可以进行单次传递以查找所有相同的对。此单次传递是O(n)操作。所以总的复杂性是:

O(n lg n + n) = O(n lg n)

答案 1 :(得分:1)

Tim在回答中指出,在排序数组中查找对的复杂性为O(n)而不是O(n^2)

为了说服自己,请考虑一个典型的O(n^2)算法: Insertion Sort

可以找到动画示例here

正如你在gif中看到的,这个算法是二次方的原因是因为,对于每个元素,它必须检查整个数组以确保这个元素必须去的地方(这个包括数组中的前一个元素!)。

另一方面,在你的情况下,你有一个有序数组:例如[0,1,3,3,6,7,7,9,10,10]

在这种情况下,你将从头开始扫描(成对),并且(因为数组是有序的)你知道一旦扫描了一个元素并且指针继续进行,就没有任何理由重新扫描以前的元素,因为否则你不会在第一时间进行。

因此,您只扫描整个数组一次:O(n)

答案 2 :(得分:0)

如果你可以分配更多的内存,你可以获得一些收益。

您可以使用哈希表到达O(n),该哈希表将数组中的任何值映射到计数器,指示您已经看到此值的频率。

如果允许值的数量是整数且在有限的范围内,则可以直接使用数组而不是哈希表。值i的索引本身为i。在这种情况下,复杂性为O(n+m),其中m是允许值的数量(因为您必须首先将0数组中的所有条目设置为nv_i,然后查看所有数组条目数对)。

两种方法都为您提供了数组中每个值的相同值的数量。我们将此数字i称为数组中值i的出现次数。然后,值(nv_i)*(nv_i-1)/2对的数量为:1st i with nv_i-1 others 2nd i with nv_i-2 others ... last i with 0

你可以配对:

(nv_i-1)+(nv_i-2)+...+0 = (nv_i)*(nv_i-1)/2

{{1}}

答案 3 :(得分:0)

我一直在想这个....我想如果你&#34;嵌入&#34;然后,==条件进入排序算法,复杂度仍为O(n lg n)。