牛客地址
解题思路
利用归并排序
- (a) 把长度为4的数组分解成两个长度为2的子数组;
- (b) 把长度为2的数组分解成两个成都为1的子数组;
- (c) 把长度为1的子数组 合并、排序并统计逆序对 ;
- (d) 把长度为2的子数组合并、排序,并统计逆序对;
合并并统计逆序对的过程
先用两个指针指向两个子数组的末尾,并每次比较两个指针指向的数字。如果第一个数组中的数字大于第二个数组中的数字,则会构成逆序对,并且增加的逆序对的数目等于第二个子数组中属于数字的个数。
实现代码
public class Solution {
private final int MOD = 1000000007;
public int InversePairs(int [] array) {
if(array == null || array.length <= 1){
return 0;
}
return mergeSort(array, 0, array.length - 1);
}
public int mergeSort(int[] array, int start, int end){
if(start == end){
return 0;
}
int mid = start + (end - start) / 2;
int left = mergeSort(array, start, mid);
int right = mergeSort(array, mid + 1, end);
int other = merge(array, start, mid, end);
return (int) ((left + right + other) % MOD);
}
public int merge(int[] array, int start, int mid, int end){
int count = 0;
int len = end - start + 1;
int[] copy = new int[len];
int index = len - 1;
int p1 = mid;
int p2 = end;
while(p1 >= start && p2 > mid){
if(array[p1] > array[p2]){
count += (p2 - mid);
count = count % MOD;
copy[index --] = array[p1--];
}
else{
copy[index --] = array[p2 --];
}
}
while(p1 >= start){
copy[index --] = array[p1--];
}
while(p2 > mid){
copy[index --] = array[p2--];
}
for(int i = 0; i < len; i++){
array[start + i] = copy[i];
}
return count;
}
}
问题
所有的返回值都为int类型,在每次count++的时候,就进去取模操作,这样就不用引入long变量,然后还得经过类型转化。