【发布时间】:2015-06-14 20:45:26
【问题描述】:
数组中相同的一对是 2 个索引 p,q 使得
0<=p<q<N 和 array[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) 用于排序数组中的线性扫描计数。
【问题讨论】:
-
由于排序会将相等的值放在一起,因此您无需检查所有
q,只需检查p附近的那些。如果您使用稳定的排序算法,您甚至不需要执行第一次测试。 -
正确,我需要检查 p 附近的值,对于 0
-
数组已排序这一事实意味着您可以一次扫描它。所以不是 O(n^2) 而是 O(n)。作为一个反例,插入排序是 O(n^2),因为对于每个元素,它必须扫描整个数组。
-
@mdm,能否请您参考我的第二部分代码,可能是我错过了您的观点,但我仍然觉得第二部分应该具有二次时间复杂度。
-
@SREEPRASADGOVINDANKUTTY 有一个平方数的对,但您可以在
O(n)中计算它