BM20 陣列中的逆序對
阿新 • • 發佈:2022-04-04
連結:https://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5
本題採用歸併排序的思想對問題進行求解,即在每次遞迴歸併中,對遞迴出的子問題考慮能組成逆序對的個數,來以此累加。
解題程式碼:
1 static int mod = (int) (1e9 + 7); 2 //逆序對問題 3 public int InversePairs(int [] array) { 4 if (array == null ||array.length == 1 ) { 5 return 0;6 } 7 return process(array,0,array.length - 1) % mod; 8 } 9 10 public int process(int[] array,int l,int r) { 11 if (l == r) { 12 return 0; 13 } 14 int mid = l + ((r - l) >> 1); 15 return (process(array,l,mid) + process(array,mid + 1,r) + merge(array,l,mid,r)) % mod;16 } 17 18 public int merge(int[] array,int l,int mid,int r) { 19 int ans = 0; 20 int i = l, j = mid + 1; 21 int[] help = new int[r - l + 1]; 22 int cnt = 0; 23 while (i <= mid && j <= r) { 24 if (array[i] > array[j]) { 25ans += r - j + 1; 26 help[cnt++] = array[i++]; 27 } 28 else { 29 help[cnt++] = array[j++]; 30 } 31 } 32 while (i <= mid) { 33 help[cnt++] = array[i++]; 34 } 35 while (j <= r) { 36 help[cnt++] = array[j++]; 37 } 38 for (int k = 0; k < r - l + 1; k++) { 39 array[k + l] = help[k]; 40 } 41 return ans % mod; 42 }
還可以借鑑這道題的思路:
1 /*利用歸併排序思想,求解部分最小和的問題 2 * 如arr = {1,3,4,2,5} ,則對於1來說左側沒有比1小的數,所以和為0 3 * 對於3來說左側有個1比3小,所以和為1 4 * 對於4來說左側有個1和3比4小,所以和為4 5 * 對於2來說左側有個1比2小,所以和為1 6 * 對於5來說左側有1,3,4,2比5小,所以和為10 所以總和為16 7 */ 8 /* 9 * 可以換一種思路進行求解: 10 * 1.對於第一個1,之後有3,4,2,5四個數都比它大,所以共要加4次 11 * 2.對於第二個3,之後有4,5兩個數都比它大,所以共要加2次 12 * 3.按照這個思路以此類推至最後一個元素 13 * 14 * 所以可以沿用歸併排序的思想,每次歸併時,如果左邊的數比右邊的數小,則加上一次左邊的這個數 15 */ 16 17 public static int MergeAll(int[] arr) 18 { 19 if (arr == null || arr.length == 1) { 20 return 0; 21 } 22 return process(arr,0,arr.length - 1); 23 } 24 25 public static int process(int[] arr,int l,int r) 26 { 27 if (l == r) { 28 return 0; 29 } 30 int mid = l + ((r - l) >> 1); 31 32 return process(arr,l,mid) + process(arr,mid + 1,r) + Merge(arr,l,mid,r); 33 } 34 35 public static int Merge(int[] arr,int l,int mid,int r) 36 { 37 int ans = 0; 38 int i = l, j = mid + 1; 39 int[] help = new int[r - l + 1]; 40 int cnt = 0; 41 while (i <= mid && j <= r) { 42 if (arr[i] < arr[j]) { 43 ans += arr[i] * (r - j + 1); 44 help[cnt++] = arr[i++]; 45 } 46 else { 47 help[cnt++] = arr[j++]; 48 } 49 } 50 while (i <= mid) { 51 help[cnt++] = arr[i++]; 52 } 53 while (j <= r) { 54 help[cnt++] = arr[j++]; 55 } 56 for (int k = 0; k < r - l + 1; k++) { 57 arr[k + l] = help[k]; 58 } 59 return ans; 60 }