逆序对
给定一个长度为 n的整数数列,请你计算数列中的逆序对的数量。
逆序对的定义如下:对于数列的第 i 个和第 j个元素,如果满足 i<j 且 a[i]>a[j],则其为一个逆序对;否则不是。
求解
- 基本思路肯定是先计算某个区间的逆序对数量,然后逐渐合并区间;
- 一旦某个区间的逆序对数量确定了,则该区间是否保持有序不重要
- 在归并排序中,假设[begin, partition] 和[partition+1, end]都是已排序好的,且对应区间的逆序对数量已经计算完毕,则合并的时候:
void merge(int arr[], int begin, int partition, int end){
const int len = end - begin + 1;
int temp[len];
int i = begin, j = partition + 1, k = 0;
while(i <= partition && j <= end){
if(arr[i] <= arr[j]){
temp[k] = arr[i];
++i;
}else{
cnt += partition - i + 1; //cnt表示累计逆序对数量
temp[k] = arr[j];
++j;
}
++k;
}
if(i > partition){
while(j <= end){
temp[k++] = arr[j++];
}
}else{
while(i <= partition){
temp[k++] = arr[i++];
}
}
for(int l = 0; l < len; ++l){
arr[begin+l] = temp[l];
}
}
当arr[j]是较小值时,对cnt进行一次累加,cnt = partition - i +1;
!真是天才的想法!
自己蠢的要去埋了自己……