问题:
给定不存在重复元素的数列a[n],问存在多少对(i, j),满足 0<=i<j<n && a[i] > a[j]
解法:归并排序
数列的逆序对数 = 左半边逆序对数 + 右半边逆序对数 + merge过程中右半边元素放置在左半边元素前面的个数
T ( n ) = 2 T ( n 2 ) + O ( n ) T(n) = 2T(\frac{n}{2}) + O(n) T(n)=2T(2n)+O(n)
故时间复杂度为 O(nlogn)
//合并a[0, n1)与a[n1, n),返回合并中发现的逆序对数
int mergeArray(int a[], int n1, int n){
int ans=0, p=0, q=n1;
int *b = new int[n];
memcpy(b, a, n*sizeof(int));
for(int i=0; i<n; i++){
//fill in a[i]
if(q>=n || (p<n1 && b[p]<b[q])){
//取前一半的数填,此时后半边已经填入了q-n1个,都和此数构成逆序对
a[i] = b[p++];
ans += q - n1;
}
else a[i] = b[q++];
}
delete[] b;
return ans;
}
//返回a[0, n)中的逆序对数,同时把a归并排序
int mergeSort(int a[], int n){
if(n==1) return 0;
int mid = n/2;
return mergeSort(a, mid) + mergeSort(a+mid, n-mid) + mergeArray(a, mid, n);
}