逆序对数目可以直接穷举,但效率很低,O(n^2)级别.
可以用树状数组写.
这里介绍运用归并排序来求逆序对数目.
归并排序过程中,针对两个内部有序的串,
实现插入排序,即两串开头的元素,小的进入目标串,直到所有元素都输出.
假设左串当前元素比右串当前元素大.
那么左串剩下的元素一定都比右串当前元素大,都是逆序对.
那么这里逆序对就有 (mid - index_left + 1 )对
累加,最后获得最终的逆序对数目.
给出代码实现:
// a:目标数组 temp:临时数组
void merge(int left,int right,int mid)
{
int index1, index2, num = left;
for(int i=left;i<=right;i++)
temp[i] = a[i];
index1 = left; index2 = mid+1;//左右子序列开始的位置
while(index1<=mid && index2<=right)
{
if(temp[index1] <= temp[index2])//取较小者放入数组
{
a[num++] = temp[index1++];
}
else
{
a[num++] = temp[index2++];
res += (mid-index1+1);//左边没比完的元素和右边这个元素构成逆序对。
}
}
while(index1 <= mid)
a[num++] = temp[index1++];
while(index2 <= right)
a[num++] = temp[index2++];
}
void sort(int left,int right)
{
if(left >= right)
return;
int mid = (left+right)/2;
sort(left,mid);
sort(mid+1,right);
merge(left,right,mid);
}