- 小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
文字题解
利用归并排序实现
在归并排序执行过程中,默认长度为1的数组是有序的
再归并合并数组的过程中,合并前,左边是有序的,右边也是有序的
统计数量,如果左边的比右边的大,那么此时左边跟右边都是有序的
则左边剩余的数+1就是这次逆序对的数量
主要难点在于要想到逆序对的数量是怎么计算出来的
代码实现
static int temp = 0;
public static int reversePair(int[] arr) {
if (arr == null || arr.length < 2) {
return 0;
}
mergeSort(arr, 0, arr.length - 1);
return temp;
}
public static void mergeSort(int[] arr, int L, int R) {
if (L == R) {
return;
}
int mid = L + ((R - L) >> 1);
mergeSort(arr, L, mid);
mergeSort(arr, mid + 1, R);
merge(arr, L, mid, R);
}
private static void merge(int[] arr, int L, int mid, int R) {
int[] help = new int[R - L + 1];
int i = 0;
int p1 = L;
int p2 = mid + 1;
while (p1 <= mid && p2 <= R) {
if (arr[p1] > arr[p2]) {
System.out.printf("[%d,%d] \n", arr[p1], arr[p2]);
//统计数量,如果左边的比右边的大,那么此时左边跟右边都是有序的
//则左边剩余的数+1就是这次逆序对的数量
temp += (mid - p1 + 1);
System.out.println(temp);
}
help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
}
//把左边剩余的数移入数组
while (p1 <= mid) {
help[i++] = arr[p1++];
}
//把右边剩余的数移入数组
while (p2 <= R) {
help[i++] = arr[p2++];
}
//改变原数组中的值,将该区间整体变成有序
for (int j = 0; j < help.length; j++) {
arr[L + j] = help[j];
}
}