題目:在陣列中的兩個數字如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數
例如在陣列{7,5,6,4}中,一共存在5對逆序對,分別是{7,6},{7,5},{7,4},{6,4},{5,4}。
看 到這個題目,我們的第一反應就是順序掃瞄整個陣列。每掃瞄到乙個陣列的時候,逐個比較該數字和它後面的數字的大小。如果後面的數字比它小,則這兩個數字就組成乙個逆序對。假設陣列中含有n個數字。由於每個數字都要和o(n)個數字做比較,因此這個演算法的時間複雜度為o(n2)。我們嘗試找找更快的演算法。
//// 我們以陣列{7,5,6,4}為例來分析統計逆序對的過程,每次掃瞄到乙個數字的時候,我們不能拿它和後面的每乙個數字做比較,否則時間複雜度就是o(n2)因此我們可以考慮先比較兩個相鄰的數字。
//// 如下圖所示,我們先把陣列分解稱兩個長度為2的子陣列,再把這兩個子陣列分別茶城兩個長度為1的子陣列。接下來一邊合併相鄰的子陣列,一邊統計逆序對的數目。在第一對長度為1的子陣列{7},{5}中7大於5,因此{7,5}組成乙個逆序對。同樣在第二對長度為1的子陣列{6},{4}中也有逆序對{6,4}。由於我們已經統計了這兩隊子陣列內部逆序對,因此需要把這兩對子陣列排序,以免在以後的統計過程中再重複統計。
//接下來我們統計兩個長度為2的子陣列之間的逆序對。
//// 我們先用兩個指標分別指向兩個子陣列的末尾,並每次比較兩個指標指向的數字。如果第乙個子陣列中的數字大於第二個子陣列中的數字,則構成逆序對,並且逆序對的數目等於第二個子陣列中的剩餘數字的個數。如果第乙個陣列中的數字小於或等於第二個陣列中的數字,則不構成逆序對。每一次比較的時候,我們都把較大的數字從後往前複製到乙個輔助陣列中去,確保輔助陣列中的數字是遞增排序的。在把較大的數字複製到陣列之後,把對應的指標向前移動一位,接著來進行下一輪的比較。
//// 經過前面詳細的討論,我們可以總結出統計逆序對的過程:先把陣列分隔成子陣列,先統計出子陣列內部的逆序對的數目,然後再統計出兩個相鄰子陣列之間的逆序對的數目。在統計逆序對的過程中,還需要對陣列進行排序。如果對排序演算法很熟悉,我們不難發現這個排序的過程就是歸併排序。
public class inversepair ;
int p = new int[a.length];
mergesort(a, 0, a.length - 1, p);
}static void merge(int array, int low, int mid, int high, int temp)
} else
}while (i <= m)
while (j <= n)
for (i = 0; i < index; i++)
}static void mergesort(int a, int low, int high, int temp) }}
樹狀陣列求逆序對 演算法系列之 陣列中的逆序對
題目 劍指offer 01 題目描述在陣列中如果前乙個數字大於後乙個數字,則稱為這個數字組合組成乙個逆序對。輸入乙個陣列,求所有的逆序對的總數。如 陣列 則它的逆序對是 7,5 7,6 7,4 5,4 6,4 總共有五個。02 解法1 類似的題目,我們的第一反應都是,固定乙個數,如7,然後從後面的數...
陣列中逆序對
題目 在陣列中的兩個數字,如果前面的乙個數字大於後面的數字,則這兩個數字為乙個逆序對。輸入乙個陣列,求這個陣列的逆序對個數。例如 給定陣列 則有 5,3 5,1 8,3 8,1 3,1 這5個逆序對。問題分析 我採用兩種方法來解決這個問題 1 考慮到二叉搜尋樹中每個節點x,它的左子樹所有關鍵字的值小...
演算法之逆序對
假設a 1.n 是乙個有n個不同數的陣列。若ia j 則對偶 i,j 稱為a的乙個逆序對 inversion 列出陣列的5個逆序對 由集合中的元素構成的什麼陣列具有最多的逆序對?它有多少逆序對?插入排序的執行時間與輸入陣列中的逆序對的數量有什麼關係?給出乙個求在n個元素的任何排列中逆序對數量的演算法...