劍指offer:(36)時間效率和空間效率的平衡 :陣列中的逆序對
阿新 • • 發佈:2018-11-09
在陣列中的兩個數字,如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個陣列中的逆序對的總數P。並將P對1000000007取模的結果輸出。 即輸出P%1000000007
package cn.com.jianzhioffer; public class Solution36 { // public static int InversePairs(int[] array) { // int length = array.length; // return mergeSort(array, 0, length - 1); // } // // private static int mergeSort(int[] data, int start, int end) { // // 遞迴終止條件 // if (start >= end) { // return 0; // } // // // 遞迴 // int mid = (start + end) / 2; // int leftCounts = mergeSort(array, start, mid); // int rightCounts = mergeSort(array, mid + 1, end); // // // 歸併排序,並計算本次逆序對數 // int[] copyArray = array;// 陣列副本,用於歸併排序 // int foreIdx = mid;// 前半部分的指標 // int backIdx = end;// 後半部分的指標 // int counts = 0;// 記錄本次逆序對數 // int idxCopy = end;// 輔助陣列的下標 // while (foreIdx >= start && backIdx >= mid + 1) { // if (array[foreIdx] > array[backIdx]) { // copyArray[idxCopy--] = array[foreIdx--]; // counts += backIdx - mid; // } else { // copyArray[idxCopy--] = array[backIdx--]; // } // } // // while (foreIdx >= start) { // copyArray[idxCopy--] = array[foreIdx--]; // } // while (backIdx >= mid + 1) { // copyArray[idxCopy--] = array[backIdx--]; // } // // for (int i = start; i <= end; i++) { // array[i] = copyArray[i]; // } // // return (leftCounts + rightCounts + counts); // } /*歸併排序的改進,把資料分成前後兩個陣列(遞迴分到每個陣列僅有一個數據項), 合併陣列,合併時,出現前面的陣列值array[i]大於後面陣列值array[j]時;則前面 陣列array[i]~array[mid]都是大於array[j]的,count += mid+1 - i 參考劍指Offer,但是感覺劍指Offer歸併過程少了一步拷貝過程。 還有就是測試用例輸出結果比較大,對每次返回的count mod(1000000007)求餘 */ public static int InversePairs(int [] array) { if(array==null||array.length==0) { return 0; } int[] copy = new int[array.length]; for(int i=0;i<array.length;i++) { copy[i] = array[i]; } int count = InversePairsCore(array,copy,0,array.length-1);//數值過大求餘 return count; } private static int InversePairsCore(int[] array,int[] copy,int low,int high) { if(low==high) { return 0; } int mid = (low+high)>>1; int leftCount = InversePairsCore(array,copy,low,mid)%1000000007; int rightCount = InversePairsCore(array,copy,mid+1,high)%1000000007; int count = 0; int i=mid; int j=high; int locCopy = high; while(i>=low&&j>mid) { if(array[i]>array[j]) { count += j-mid; copy[locCopy--] = array[i--]; if(count>=1000000007)//數值過大求餘 { count%=1000000007; } } else { copy[locCopy--] = array[j--]; } } for(;i>=low;i--) { copy[locCopy--]=array[i]; } for(;j>mid;j--) { copy[locCopy--]=array[j]; } for(int s=low;s<=high;s++) { array[s] = copy[s]; } return (leftCount+rightCount+count)%1000000007; } public static void main(String[] args) { int[] array = {1,2,3,4,5,0}; System.out.println(InversePairs(array)); } }