本文參考自《劍指offer》一書,代碼採用Java語言。html
更多:《劍指Offer》Java實現合集 java
在數組中的兩個數字若是前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個數組中的逆序對的總數。數組
若是遍歷數組,對每一個數字都和後面的數字比較大小,時間複雜度爲O(n^2),效率過低。post
利用歸併排序的思想,先將數組分解成爲n個長度爲1的子數組,而後進行兩兩合併同時排好順序。測試
在對兩個子區域合併排序時,記左邊區域(下標爲start~mid)的指針爲i,右邊區域(下標爲mid+1~end)的指針爲j,兩個指針都指向該區域內最大的數字,排序時:url
(1)若是i指向的數字大於j指向的數字,說明:逆序對有j-mid個,咱們把i指向的數字放入臨時建立的排序數組中,而後令i-1,指向該區域前一個數字,繼續進行排序;指針
(2)若是i指向的數字小於等於j指向的數字,說明暫時不存在逆序對,將j指向的數字放入臨時建立的排序數組中,而後令j-1,指向該區域前一個數字,繼續進行排序;htm
(3)某一子區域數字都放入排序數組後,將另外一個子區域剩下的數字放入排序數組中,完成排序;blog
(4)最後將排序好的數字按順序賦值給原始數組的兩個子區域,以便合併後的區域與別的區域合併。排序
測試算例
1.功能測試(普通數組,遞增數組,遞減數組,含重複數字)
2.邊界值測試(數組只有兩個數字,只有一個數字)
2.特殊測試(null)
//題目:在數組中的兩個數字若是前面一個數字大於後面的數字,則這兩個數字組 //成一個逆序對。輸入一個數組,求出這個數組中的逆序對的總數。 public class InversePairs { public static int inversePairs(int [] array) { if(array==null || array.length<=0) return 0; int count=getCount(array,0,array.length-1); return count; } private static int getCount(int[] array,int start,int end){ if(start>=end) return 0; int mid=(end+start)>>1; int left=getCount(array,start,mid); int right=getCount(array,mid+1,end); //合併 int count=0; int i=mid; //左邊區域的指針 int j=end; //右邊區域的指針 int[] temp= new int[end-start+1]; //臨時區域 int k=end-start; //臨時區域的指針 while(i>=start && j>=mid+1){ if(array[i]>array[j]){ count+=(j-mid); temp[k--]=array[i--]; }else{ temp[k--]=array[j--]; } } while(i>=start) temp[k--]=array[i--]; while(j>=mid+1) temp[k--]=array[j--]; for(k=0;k<temp.length;k++) array[k+start]=temp[k]; return count+left+right; } }
1.要對歸併排序的實現很是熟練。