在数组中查找满足i<j且a[i]>a[j]条件的(i,j)对的总数。

9

如问题所述,需要找到数组中满足以下条件的 (i,j) 对的总数:

(1) **i<j** 
(2) **a[i]>a[j]**

其中i和j是数组的索引。没有空间限制。

我的问题是

 1) Is there any approach which takes less than O(N^2) time?
 2) if so what is least complexity ?
 3) How do we prove that ? 

我希望我的问题表述清楚了。
我的方法如下:
一种解决这个问题的方法是使用暴力枚举,时间复杂度为O(N^2)。
但我认为应该有更优化的解决方案,至少要达到O(NlogN)的时间复杂度。我这样想的原因如下:
第一点:
对于按升序排序一个数组的条件,我们有:对于i
第二点:
假设我们有一个元素数组,如下所示:4、9、7、3、2、1、8、12
我们计算上述条件ia[j]对于元素4,当i=0指向4时,j的可能值为3、4、5。由于a[0]>a[3],a[0]>a[4],a[0]>a[5],所以现在我的(i,j)对的总数为3。
下一次当我将i(索引)增加到1时,j的可能值为2、3、4、5、6。但我们应该利用这样一个事实:当i=0(当a[i]=4)时,我们已经计算出小于a[i=0]的3个元素,这些元素又小于a[i=1],所以我将不会比较9与3、2、1(为了减少不必要的计算)。如果我们可以去除不必要的计算,那么我们就可以将时间复杂度降低到小于O(N^2),否则不存在小于O(N^2)的解决方案。但如果有解决方案,我们该如何做呢?我试图制作图表,但我的努力是徒劳的。
方法一:
为了获得O(nlogn)的时间复杂度,我认为我们需要调整快速排序或归并排序来获得解决方案,但问题在于,如果我们对数组进行排序,我们将失去元素的实际位置。
方法二:
为了在O(NlogN)的时间内得到解决方案,我认为使用树可能会得到优化的解决方案。我没有得到任何线索。
方法三:
如果存在任何O(N)时间算法,则应使用哈希。但在这种情况下,简单的哈希无法工作。
因此,请告诉我上述哪些直觉或方法是正确的(如果正确,哪种方法将导致优化的解决方案以及如何)。

你是指“小于O(N^2)”吗?我这么问是因为从技术上讲,O(N*2)和O(N)是一样的,而且你所说的“O(N2)”并不清楚。 - RBarryYoung
你是想找到这样的配对的准确数量,还是要列举它们? - A. Webb
一些额外(更复杂)的算法:在值a[i]上使用树状数组(需要一些O(NlogN)预处理)。将每个(i, a[i])解释为2D点,并使用正交范围最小查询算法。 - Nabb
@A.Webb:只是在尝试计数.. - Imposter
@Nabb:一个好的参考资料会很有帮助...... - Imposter
2个回答

13
您可以使用与合并排序类似的算法来计算逆序对,如此处所述。思路是在合并排序数组时计数每一步更改了多少个逆序对。
另一种方法是使用顺序统计树。您将数组元素依次插入此树中,并在每次插入后查看前面的元素中有多少个大于它。
替代顺序统计树的是可索引跳表
这两种算法的时间复杂度均为O(N log N)。
要获得逆序对的近似数量,可以使用具有某些限制的O(N)时间复杂度。我们可以像修改合并排序一样修改桶排序
在"散布"阶段,我们应该估计较大元素的桶中有多少元素,同时在某个桶的末尾插入元素(每个桶中的元素保持原始顺序)。
在"排序"阶段,我们应该在相同的方式下修改排序算法(最可能是插入排序)。在将元素插入到其正确位置时,我们应该计算它跳过了多少其他元素。
至于限制,这个算法只能处理数字(或可轻松转换为数字的对象),而且我们应该事先知道这些数字是如何分布的。因此,如果我们有一个均匀分布的整数数组,这个算法应该正常工作。

顺序统计树听起来是个不错的想法。它是这样的吗:二叉搜索树加上每个节点跟踪其右子树中包含更大元素的子节点数。插入将在我们遍历树时更新此计数,并计算逆序对的数量,这些数量可以从我们向下遍历树时找到。大致正确吗? - Paresh
@Paresh:没错。除此之外,每个节点还会跟踪以其为根的子树中节点的数量。 - Evgeny Kluev
@EvgenyKluev:好的解决方案。我猜想,既然涉及到计数,那么一个适当的哈希(双倍或更多)函数应该可以在O(N)中完成工作,因为没有空间要求。 - Imposter
1
@冒名顶替者:我认为哈希在这里没有帮助。现在我正在考虑其他O(N)的解决方案。 - Evgeny Kluev
我在面试中被问到这个问题,结果完全崩溃了。感谢提供资源。 - RYS

6

这样的一对数字被称为数组中的逆序对。它是衡量数组接近排序程度的一个指标。您可以修改归并排序, 以在 O(nlogn) 时间内高效计算逆序对数。有关详细信息,请参阅此文


1
提供的链接显示403禁止访问,因此请使用Web Archive [https://web.archive.org/web/20170222074703/http://www.cs.umd.edu/class/fall2009/cmsc451/lectures/Lec08-inversions.pdf]。 - BluePie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接