求數組中的逆序對的數量----劍指offer36題


在數組中的兩個數字,如果前面一個數字大於后面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個數組中的逆序對的總數:

如數組{7,5,6,4},逆序對總共有5對,{7,5},{7,6},{7,4},{5,4},{6,4};

思路1:暴力解法,順序掃描整個數組,每掃描到一個數字的時候,逐個比較該數字和它后面的數字的大小。如果后面的數字比它小,則這兩個數字就組成一個逆序對。假設數組中含有n個數字,由於每個數字都要和O(n)個數字作比較,因此這個算法的時間復雜度是O(n2)。

思路2:分治思想,采用歸並排序的思路來處理,如下圖,先分后治:

 

先把數組分解成兩個長度為2的子數組,再把這兩個子數組分解成兩個長度為1的子數組。接下來一邊合並相鄰的子數組,一邊統計逆序對的數目。在第一對長度為1的子數組{7}、{5}中7>5,因此(7,5)組成一個逆序對。同樣在第二對長度為1的子數組{6},{4}中也有逆序對(6,4),由於已經統計了這兩對子數組內部的逆序對,因此需要把這兩對子數組進行排序,避免在之后的統計過程中重復統計。

逆序對的總數=左邊數組中的逆序對的數量+右邊數組中逆序對的數量+左右結合成新的順序數組時中出現的逆序對的數量;

總結統計數組逆序對的過程:先把數組分隔成子數組,先統計出子數組內部的逆序對的數目,然后再統計出兩個相鄰子數組之間的逆序對的數目。在統計逆序對的過程中,還需要對數組進行排序,其實這個排序過程就是歸並排序的思路。

代碼實現思路如下:

//數組中的逆序對
    public static int InversePairs(int[] array){
        if(array==null||array.length<=1)
            return 0;
        int[] copy = new int[array.length];
        for(int i=0;i<array.length;i++){
            copy[i] = array[i];
        }
        return mergeCount(array, copy, 0, array.length-1);
    }
    
    public static int mergeCount(int[] array, int[] copy, int start, int end){
        if(start==end){
            copy[start] = array[start];
            return 0;
        }
        int mid = (start+end)>>1;
        int leftCount = mergeCount(copy, array, start, mid);
        int rightCount = mergeCount(copy, array, mid+1, end);
        
        int i = mid;//i初始化為前半段最后一個數字的下標
        int j = end;//j初始化為后半段最后一個數字的下標
        int index = end;//輔助數組復制的數組的最后一個數字的下標
        int count = 0;//計數--逆序對的數目
        while(i>=start&&j>=mid+1){
            if(array[i]>array[j]){
                copy[index--] = array[i--];
                count += j-mid;
            }else{
                copy[index--] = array[j--];
            }
        }
        for(;i>=start;i--){
            copy[index--] = array[i];
        }
        for(;j>=mid+1;j--){
            copy[index--] = array[j];
        }
        return leftCount+rightCount+count;
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM