题解 | #数组中的逆序对#
数组中的逆序对
http://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5
//统计逆序对的个数
int ret = 0;
public int InversePairs(int[] array) {
if (array == null || array.length == 0) {
return 0;
}
//使用归并排序的方式统计
divide(array, 0, array.length - 1);
return ret;
}
private void divide(int[] array, int start, int end) {
//递归的终止条件
if (start >= end) {
return;
}
//计算中间值,注意溢出
int mid = start + (end - start) / 2;
//递归分
divide(array, start, mid);
divide(array, mid + 1, end);
//治
merge(array, start, mid, end);
}
private void merge(int[] arr, int start, int mid, int end) {
int[] tmp = new int[end - start + 1];
//存一下变量
int i = start;
int j = mid + 1;
int k = 0;
//下面就开始两两进行比较,若前面的数大于后面的数,就构成逆序对
while (i <= mid && j <= end) {
//若前面小于后面,直接存进去,并且移动前面数所在的数组的指针即可
if (arr[i] <= arr[j]) {
tmp[k++] = arr[i++];
} else {
//a[i]>a[j]了,那么这一次,从a[i]开始到a[mid]必定都是大于这个a[j]的,因为此时分治的两边已经是各自有序了
tmp[k++] = arr[j++];
ret = (ret + mid - i + 1) % 1000000007;
}
}
//各自还有剩余的没比完,直接赋值即可
//由于上面的循环条件可知,i和j中必定只有一个可能还有剩余没循环完,所以下面两个循环也只会执行一个。
while (i <= mid) {
tmp[k++] = arr[i++];
}
while (j <= end) {
tmp[k++] = arr[j++];
}
//覆盖原数组
for (k = 0; k < tmp.length; k++) {
arr[start + k] = tmp[k];
}
}
}