【Java】 劍指offer(51)數組中的逆序對

本文參考自《劍指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)

Java代碼、

//題目:在數組中的兩個數字若是前面一個數字大於後面的數字,則這兩個數字組
//成一個逆序對。輸入一個數組,求出這個數組中的逆序對的總數。

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.要對歸併排序的實現很是熟練。

  

更多:《劍指Offer》Java實現合集 

相關文章
相關標籤/搜索