package leo.class03_04; import leo.util.ArrayUtil; /** * @author Leo * @ClassName ReversePair * @DATE 2020/11/23 9:48 下午 * @Description 在一段数组中 返回有多少逆序对 * 合并的时候 两侧下标-- * 任何一个前面的数a,和任何一个后面的数b, * 如果(a,b)是降序的 */ public class ReversePair { public static int reversePairNumber(int[] arr) { if (arr.length < 2 || arr == null) { return 0; } return process(arr, 0, arr.length - 1); } private static int process(int[] arr, int l, int r) { if (l == r) { return 0; } int mid = l + ((r - l) >> 1); return process(arr, 0, mid) + process(arr, mid + 1, r) + merge(arr, l, mid, r); } private static int merge(int[] arr, int l, int m, int r) { int[] help = new int[r - l + 1]; int i = help.length - 1; int p1 = m; int p2 = r; int res = 0; while (p1 >= l && p2 > m) { res += arr[p1] > arr[p2] ? (p2 - m) : 0; help[i--] = arr[p1] > arr[p2] ? arr[p1--] : arr[p2--]; } while (p1 >= l) { help[i--] = arr[p1--]; } while (p2 > m) { help[i--] = arr[p2--]; } for (i = 0; i < help.length; i++) { arr[l + i] = help[i]; } return res; } } class ReversePair1{ public static int reversePairNumber(int[] arr) { if (arr.length < 2 || arr == null) { return 0; } return process(arr, 0, arr.length - 1); } private static int process(int[] arr, int l, int r) { if (l == r) { return 0; } int mid = l + ((r - l) >> 1); return process(arr, l, mid) + process(arr, mid + 1, r) + merge(arr, l, mid, r); } private static int merge(int[] arr, int l, int m, int r) { int[] help = new int[r - l + 1]; int i = help.length - 1; int p1 = m; int p2 = r; int res = 0; while (p1 >= l && p2 > m) { res += arr[p1] > arr[p2] ? (p2 - m) : 0; help[i--] = arr[p1] > arr[p2] ? arr[p1--] : arr[p2--]; } while (p1 >= l) { help[i--] = arr[p1--]; } while(p2>m){ help[i--] = arr[p2--]; } for (i = 0; i < help.length; i++) { arr[l + i] = help[i]; } return res; } } class ReversePair2{ public static int reversePairNumber(int[] arr) { if (arr.length < 2 || arr == null) { return 0; } return process(arr, 0, arr.length - 1); } private static int process(int[] arr, int l, int r) { if (l == r) { return 0; } int mid = l + ((r - l) >> 1); return process(arr, l, mid) + process(arr, mid + 1, r) + merge(arr, l, mid, r); } private static int merge(int[] arr, int l, int m, int r) { int res = 0; int[] help = new int[r - l + 1]; int p1 = m; int p2 = r; int i = help.length - 1; while (p1 >= l && p2 > m) { res += arr[p1] > arr[p2] ? (p2 - m) : 0; help[i--] = arr[p1] > arr[p2] ? arr[p1--] : arr[p2--]; } while (p1 >= l) { help[i--] = arr[p1--]; } while (p2 > m) { help[i--] = arr[p2--]; } for (i = 0; i < help.length; i++) { arr[l + i] = help[i]; } return res; } } class ReversePair3 { public static int reversePairNumber(int[] arr) { if (arr.length < 2 || arr == null) { return 0; } return process(arr, 0, arr.length - 1); } private static int process(int[] arr, int l, int r) { if(l==r){ return 0; } int m = l + ((r - l) >> 1); return process(arr, l, m) + process(arr, m + 1, r) + merge(arr, l, m, r); } private static int merge(int[] arr, int l, int m, int r) { int p1 = m; int p2 = r; int[] help = new int[r - l + 1]; int i = help.length - 1; int res = 0; while (p1 >= l && p2 > m) { res += arr[p1] > arr[p2] ? p2 - m : 0; help[i--] = arr[p1] > arr[p2] ? arr[p1--] : arr[p2--]; } while (p1 >= l) { help[i--] = arr[p1--]; } while(p2>m){ help[i--] = arr[p2--]; } for (i = 0; i < help.length; i++) { arr[l + i] = help[i]; } return res; } } class ReversePair4{ public static int reversePairNumber(int[] arr) { if (arr.length < 2 || arr == null) { return 0; } return process(arr, 0, arr.length - 1); } private static int process(int[] arr, int l, int r) { if (l == r) { return 0; } int m = l + ((r - l) >> 1); return process(arr, l, m) + process(arr, m + 1, r) + merge(arr, l, m, r); } private static int merge(int[] arr, int l, int m, int r) { int p1 = m; int p2 = r; int[] help = new int[r - l + 1]; int i = help.length - 1; int res = 0; while (p1 >= l && p2 > m) { res += arr[p1] > arr[p2] ? p2 - m : 0; help[i--] = arr[p1] > arr[p2] ? arr[p1--] : arr[p2--]; } while (p1 >= l) { help[i--] = arr[p1--]; } while(p2>m){ help[i--] = arr[p2--]; } for (i = 0; i < help.length; i++) { arr[l + i] = help[i]; } return res; } } class ReversePair5{ public static int reversePairNumber(int[] arr) { if (arr.length < 2 || arr == null) { return 0; } return process(arr, 0, arr.length - 1); } private static int process(int[] arr, int l, int r) { if (l == r) { return 0; } int m = l + ((r - l) >> 1); return process(arr, l, m) + process(arr, m + 1, r) + merge(arr, l, m, r); } private static int merge(int[] arr, int l, int m, int r) { int[] help = new int[r - l + 1]; int i = help.length - 1; int p1 = m; int p2 = r; int res = 0; while (p1 >= l && p2 > m) { res += arr[p1] > arr[p2] ? p2 - m : 0; help[i--] = arr[p1] > arr[p2] ? arr[p1--] : arr[p2--]; } while (p1 >= l) { help[i--] = arr[p1--]; } while (p2 > m) { help[i--] = arr[p2--]; } for (i = 0; i < help.length; i++) { arr[l + i] = help[i]; } return res; } } class TestReversePair{ public static int reversePairNumber(int[] arr) { int res = 0; for (int i = arr.length-2; i >=0 ; i--) { for (int j = arr.length-1; j >i ; j--) { if (arr[i] > arr[j]) { res += 1; } } } for (int i = 1; i < arr.length; i++) { for (int j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j--) { swap(arr, j, j + 1); } } return res; } private static void swap(int[] arr, int i, int j) { if (i == j || arr[i] == arr[j]) { return; } arr[i] = arr[i] ^ arr[j]; arr[j] = arr[i] ^ arr[j]; arr[i] = arr[i] ^ arr[j]; } public static void main(String[] args){ int testTime = 1000; int sizeMax = 30; int range = 50; System.out.println("start!"); for (int i = 0; i < testTime; i++) { int[] arr = randomArray(sizeMax, range); int[] copyArr = copyArray(arr); int num = ReversePair5.reversePairNumber(arr); int copyNum = reversePairNumber(copyArr); if (num != copyNum) { System.out.println("num : "+num); System.out.println("copyNum : "+copyNum); return; } if (!ArrayUtil.isEqual(arr, copyArr)) { System.out.println("arr fuck!!"); return; } } System.out.println("end!"); } private static int[] copyArray(int[] arr) { int[] copyArr = new int[arr.length]; for (int i = 0; i < copyArr.length; i++) { copyArr[i] = arr[i]; } return copyArr; } private static int[] randomArray(int sizeMax, int range) { int[] arr = new int[(int) (sizeMax * Math.random() + 1)]; for (int i = 0; i < arr.length; i++) { arr[i] = (int) ((range * Math.random() + 1) - (range * Math.random() + 1)); } return arr; } }