有一组数,对于其中任意两个数组,若前面一个大于后面一个数字,则这两个数字组成一个逆序对。请设计一个高效的算法,计算给定数组中的逆序对个数。
给定一个int数组A和它的大小n,请返回A中的逆序对个数。保证n小于等于5000。
测试样例:
[1,2,3,4,5,6,7,0],8
返回:7
package com.mico.alex;
import java.util.Scanner;
public class GetReverseNum {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
int n = scanner.nextInt();
int[] A = new int[n];
for (int i = 0; i < n; i++) {
A[i] = scanner.nextInt();
}
System.out.println(count(A, n));
}
}
public static int count(int[] A, int n) {
return mergeSort(A, 0, n - 1);
}
public static int merge(int[] A, int low, int mid, int high) {
int[] B = new int[high - low + 1];
int i = low;
int j = mid + 1;
int index = 0;
int reverseNum = 0;
while (i <= mid && j <= high) {
if (A[i] <= A[j]) {
B[index++] = A[i];
i++;
} else {
B[index++] = A[j];
j++;
reverseNum += mid - i + 1;
}
}
while (i <= mid) {
B[index++] = A[i++];
}
while (j <= high) {
B[index++] = A[j++];
}
for (int k = 0; k < B.length; k++) {
A[low + k] = B[k];
}
return reverseNum;
}
public static int mergeSort(int[] A, int start, int high) {
if (start >= high) {
return 0;
}
int mid = (start + high) / 2;
int count1 = mergeSort(A, start, mid);
int count2 = mergeSort(A, mid + 1, high);
return count1 + count2 + merge(A, start, mid, high);
}
}