描述:
在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。给你一个数组,求出这个数组中逆序对的总数。
概括:如果a[i] > a[j] 且 i < j, a[i] 和 a[j] 构成一个逆序对。
样例:
序列 [2,
4, 1, 3, 5]
中,有 3 个逆序对 (2,
1)
, (4,
1)
, (4,
3)
,则返回 3
。
思路:
归并排序,复制一个数组保存排序结果,然后递归解题。一开始嵌套for循环来做,超时了,参考了其他人的方法
public class Solution {
/**
* @param A an array
* @return total of reverse pairs
*/
//归并排序
public long reversePairs(int[] A) {
// Write your code here
long result = 0;
if(A == null || A.length == 0){
return result;
}
int[] a = new int[A.length];
for(int i = 0;i<A.length;i++){
a[i] = A[i];
}
result = search(A , a , 0 , A.length - 1);
return result;
}
public long search(int[] A , int[] a , int low , int high){
if(high == low){
return 0;
}
int mid = (low + high)/2;
long left = search(A , a , low , mid);
long right = search(A , a , mid + 1 , high);
int i = mid;
int j =high;
long result = 0;
int copy = high;
while(i>=low && j>mid){
if(A[i] > A[j]){
a[copy--] = A[i--];
result += j-mid;
}else{
a[copy--] = A[j--];
}
}
for(;i>=low;i--){
a[copy--] = A[i];
}
for(;j>mid;j--){
a[copy--] = A[j];
}
for(int p = low;p<=high;p++){
A[p] = a[p];
}
return (result+left+right);
}
}