逆序对定义:设A[1..n]是一个包含n个不同数的数组。如果在i<j的情况下,有A[i] > A[j],则(i,j)就称为A中的一个逆序对(inversion)。
现给出一个算法,其可以用O(n*lgn)的最坏情况运行时间,确定n个元素的任何排列中逆序对的数量。
简单的算法实现思想:我们可以单纯的通过从前往后的逐一比对来确定逆序对的数量,虽然实现简单,但这样一来时间复杂度将会上升为O(n*n),不符合我们的要求。
改进的算法实现思想:众所周知归并排序的时间复杂度为O(cn*lgn + cn),其中c为常数。因此我们可以通过对归并排序算法稍加改进来达到目的。即在每一次归并两个子数组的同时以左边的子数组的最大值为基准比对右边的子数组中的每个元素,只要左边子数组的最大值未复制回上层数组中,右边数组中所有已经复制到上层数组中的元素均对应一个逆序对,当左边子数组最大值被复制到上层后,如果右边子数组未复制完毕,则将右边最大子数组中的其余元素复制到上层对应位置,若右子数组已经复制完毕则不做任何操作,并终止当前层逆序对计数。例如在归并排序的某一层中有如下两个子序列:
左数组:2 5 9 12
右数组:3 7 7 19
由于左右数组都是有序的,那么当前层所有所有元素被复制回上层后共出现了3个逆序对,分别由右数组的3、7、7分别产生的,之后将右边子数组中的19复制到上层中。最终经层层处理最终可以统计出数组中逆序对的总数量。
时间复杂读分析:不难发现,求逆序对的时间和归并排序大体相当,为O(cn*lgn + cn).若c等于1则简化为O(n*lgn + n),也即O(n*(lgn + 1))。
时间: 2024-10-20 06:08:08