题目 : 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
思路 : 经典的归并排序的分治思想
public class Solution {
public static void main(String[] args) {
int [] array = {2,1,4,3,5,1};
Solution solution = new Solution();
System.out.println(solution.inversePairs(array));
}
//统计逆序对的个数
int cnt;
public int inversePairs(int [] array) {
if (array.length != 0) {
divide(array, 0, array.length-1);
}
return cnt;
}
//归并排序的分
public void divide(int [] arr,int start ,int end) {
//递归的终止条件
if (start >= end) {
return;
}
//计算出中间值,注意溢出
int mid = start + (end - start)/2;
//递归分
divide(arr, start, mid);
divide(arr, mid+1, end);
//递归的治
merge(arr, start, mid, end);
}
public void merge (int []arr,int start, int mid, int end) {
int [] temp = new int [end - start +1];
//存一下变量
int i = start ,j = mid + 1,k = 0;
//下面就进行两两比较,若前面的数大于后面的数,就构成逆序对
while (i <= mid && j <= end) {
//若前面小于后面,直接存进去,并且移动前面数所在的数组的指针即可
if (arr[i] <= arr[j]) {
temp[k++] = arr[i++];
} else {
temp[k++] = arr[j++];
//a[i]>a[j]了,那么这一次,从a[i]开始到a[mid]必定都是大于这个a[j]的
//因此此时分治的两边已经是各自有序的了
cnt = (cnt + mid - i + 1)%1000000007;
}
}
//各自还有剩余的没比完,直接赋值即可
while (i <= mid) {
temp[k++] = arr[i++];
}
while (j <= end) {
temp[k++] = arr[j++];
}
//覆盖原
for (int k2 = 0; k2 < temp.length; k2++) {
arr[start+ k2] = temp[k2];
}
}
}