【劍指Offer學習】【面試題36:數組中的逆序對】,劍指offer

來源:互聯網
上載者:User

【劍指Offer學習】【面試題36:數組中的逆序對】,劍指offer
題目:在數組中的兩個數字如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個數組中的逆序對的總數。舉例分析

  例如在數組{7, 5, 6, 4 中, 一共存在5 個逆序對,分別是(7, 6)、(7,5),(7, 4)、(6, 4)和(5, 4)。

解題思路:

第一種:直接求解

  順序掃描整個數組。每掃描到一個數位時候,逐個比較該數字和它後面的數位大小。如果後面的數字比它小,則這兩個數字就組成了一個逆序對。假設數組中含有n 個數字。由於每個數字都要和O(n)個數字作比較, 因此這個演算法的時間複雜度是O(n^2)。

第二種:分析法

  我們以數組{7, 5, 6, 4}為例來分析統計逆序對的過程。每次掃描到一個數位時候,我們不能拿它和後面的每一個數字作比較,否則時間複雜度就是O(n^5),因此我們可以考慮先比較兩個相鄰的數字。

  5 . 1 ( a )和圖5.1 ( b)所示,我們先把數組分解成兩個長度為2的子數組, 再把這兩個子數組分別拆分成兩個長度為1 的子數組。接下來一邊合并相鄰的子數組, 一邊統計逆序對的數目。在第一對長度為1 的子數組{7}、{5}中7 大於5 , 因此(7, 5)組成一個逆序對。同樣在第二對長度為1 的子數組{6}、{4}中也有逆序對(6, 4)。由於我們已經統計了這兩對子數組內部的逆序對,因此需要把這兩對子數組排序( 圖5.1 ( c)所示),以免在以後的統計過程中再重複統計。

 圖中省略了最後一步, 即複製第二個子數組最後剩餘的4 到輔助數組中.
(a) P1指向的數字大於P2指向的數字,表明數組中存在逆序對.P2 指向的數字是第二個子數組的第二個數字, 因此第二個子數組中有兩個數字比7 小. 把逆序對數目加2,並把7 複製到輔助數組,向前移動P1和P3.
(b) P1指向的數字小子P2 指向的數字,沒有逆序對.把P2 指向的數字複製到輔助數組,並向前移動P2 和P3 .
(c) P1指向的數字大於P2 指向的數字,因此存在逆序對. 由於P2 指向的數字是第二個子數組的第一個數字,子數組中只有一個數字比5 小. 把逆序對數目加1 ,並把5複製到輔助數組,向前移動P1和P3 .

  接下來我們統計兩個長度為2 的子數組之間的逆序對。我們在圖5.2 中細分圖5.1 ( d)的合并子數組及統計逆序對的過程。
  我們先用兩個指標分別指向兩個子數組的末尾,並每次比較兩個指標指向的數字。如果第一個子數組中的數字大於第二個子數組中的數字,則構成逆序對,並且逆序對的數目等於第二個子數組中剩餘數位個數(5.2 (a)和圖5.2 (c)所示)。如果第一個數組中的數字小於或等於第二個數組中的數字,則不構成逆序對(5.2 (b)所示〉。每一次比較的時候,我們都把較大的數字從·後往前複製到一個輔助數組中去,確保輔助數組中的數字是遞增排序的。在把較大的數字複製到輔助數組之後,把對應的指標向前移動一位,接下來進行下一輪比較。
  經過前面詳細的詩論, 我們可以總結出統計逆序對的過程:先把數組分隔成子數組, 先統計出子數組內部的逆序對的數目,然後再統計出兩個相鄰子數組之間的逆序對的數目。在統計逆序對的過程中,還需要對數組進行排序。如果對排序賀,法很熟悉,我們不難發現這個排序的過程實際上就是歸併排序。

代碼實現:
public class Test36 {    public static int inversePairs(int[] data) {        if (data == null || data.length < 1) {            throw new IllegalArgumentException("Array arg should contain at least a value");        }        int[] copy = new int[data.length];        System.arraycopy(data, 0, copy, 0, data.length);        return inversePairsCore(data, copy, 0, data.length - 1);    }    private static int inversePairsCore(int[] data, int[] copy, int start, int end) {        if (start == end) {            copy[start] = data[start];            return 0;        }        int length = (end - start) / 2;        int left = inversePairsCore(copy, data, start, start + length);        int right = inversePairsCore(copy, data, start + length + 1, end);        // 前半段的最後一個數位下標        int i = start + length;        // 後半段最後一個數位下標        int j = end;        // 開始拷貝的位置        int indexCopy = end;        // 逆序數        int count = 0;        while (i >= start && j >= start + length + 1) {            if (data[i] > data[j]) {                copy[indexCopy] = data[i];                indexCopy--;                i--;                count += j - (start + length); // 對應的逆序數            } else {                copy[indexCopy] = data[j];                indexCopy--;                j--;            }        }        for (; i >= start; i--) {            copy[indexCopy] = data[i];            indexCopy--;            i--;        }        for (; j >= start + length + 1; j--) {            copy[indexCopy] = data[j];            indexCopy--;            j--;        }        return count + left + right;    }    public static void main(String[] args) {        int[] data = {1, 2, 3, 4, 7, 6, 5};        System.out.println(inversePairs(data)); // 3        int[] data2 = {6, 5, 4, 3, 2, 1};        System.out.println(inversePairs(data2)); //  15        int[] data3 = {1, 2, 3, 4, 5, 6};        System.out.println(inversePairs(data3)); // 0        int[] data4 = {1};        System.out.println(inversePairs(data4)); // 0        int[] data5 = {1, 2};        System.out.println(inversePairs(data5)); // 0        int[] data6 = {2, 1};        System.out.println(inversePairs(data6)); // 1        int[] data7 = {1, 2, 1, 2, 1};        System.out.println(inversePairs(data7)); // 3    }}
運行結果

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.