7、逆序对个数
题:一个数列,如果左边的数大,右边的数小,则称这两个数为一个逆序对,求出一个数列中有多少个逆序对
思路:参照归并排序
package com.gh.check01;
public class _04_排序之归并排序 {
private static int[] helper;
private static int num=0;//记录逆序数
public static void main(String[] args) {
int[] arr = {2,5,3,1,6,4,7,4,0};
sort(arr);
for(int i=0; i<arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
public static void sort(int[]arr) {
helper = new int[arr.length];
sort(arr, 0, arr.length-1);
}
public static void sort(int[]arr, int p, int r) {
if(p<r) {
int mid = p + ((r-p)>>1);
sort(arr, p, mid); //对左侧排序
sort(arr, mid+1, r); //对右侧排序
merge(arr, p,mid, r); //合并
}
}
public static void merge(int[]arr, int p, int mid,int r) {
//拷贝到辅助空间的相同位置
for(int i=0; i<arr.length; i++) {
helper[i] = arr[i];
}
//辅助数组的两个指针
int left = p, right = mid+1;
//原始数组的指针
int current = p;
while(left<=mid && right<=r) {
if(helper[left] <= helper[right]) {
arr[current++] = helper[left++];
}else {
arr[current++] = helper[right++];
num+=mid-left+1;
}
}
//做完之后,左指针可能没到头,若右边剩余在原数组中位置不变
while(left<=mid) {
arr[current++]=helper[left++];
}
}
}