问题:
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
分析:
(1)使用蛮力法进行穷举:很遗憾,时间上只能通过50%;
(2)归并排序+插入排序:很遗憾,时间上只能通过75%
code1:穷举
public int InversePairs(int[] array) { if (array == null || array.length <= 1) { return 0; } // 暴力破解:时间复杂度不满足 long count = 0; for (int i = 1; i < array.length; i++) { for (int j = i - 1; j >= 0; j--) { if (array[j] > array[i]) { count++; } } } int result = (int) count % 1000000007; }
code2:归并+插入
1 public int InversePairs(int[] array) { 2 if (array == null || array.length <= 1) { 3 return 0; 4 } 5 // 借鉴别人的思想,使用归并排序 6 long res = mergeSort(array, 0, array.length - 1); 7 // System.out.println(Arrays.toString(array)); 8 // System.out.println(res); 9 return (int) (res % 1000000007); 10 } 11 // 改进的归并排序 12 public long mergeSort(int[] dp, int start, int end) { 13 int len = (end - start); 14 if (len == 0) { 15 return 0; 16 } else if (len == 1) { 17 if (dp[start] > dp[end]) { 18 int temp = dp[end]; 19 dp[end] = dp[start]; 20 dp[start] = temp; 21 return 1; 22 } else { 23 return 0; 24 } 25 } else { 26 int mid = len / 2; 27 long right = mergeSort(dp, start, start + mid); 28 long left = mergeSort(dp, start + mid + 1, end); 29 long count = 0; 30 // 子序列使用插入排序 31 for (int i = start + mid + 1; i <= end; i++) { 32 int cur = dp[i]; 33 int j; 34 for (j = i - 1; j >= start; j--) { 35 if (dp[j] > cur) { 36 dp[j + 1] = dp[j]; 37 count++; 38 } else { 39 break; 40 } 41 } 42 if (j != i - 1) { 43 dp[j + 1] = cur; 44 } 45 } 46 return (count + right + left); 47 } 48 }
code3:纯归并