斯坦福演算法設計和分析_3. 分治演算法
阿新 • • 發佈:2020-01-14
本文預計閱讀時間4分鐘,在讀的過程中你需要帶著以下問題:
我們首先想到的就是暴力窮舉搜尋法,輸入一個數組A,裡面包含不同的整數,輸出的是它的逆序對個數,以上就是暴力解法的虛擬碼。外層迴圈i表示從左到右的遍歷陣列A中的元素,內層迴圈j是沒有與i對比過的元素,逆序了就累加。它的缺點是時間複雜度很高,O(n^2)。
分而治之思想
如果我們用分治演算法來算這個問題的話,第一個步驟就是把陣列A劃分成更小的子問題,我們把A平均的劃分成兩個部分,左邊和右邊,這樣陣列規模就變小了,這樣劃分下就有三種情況:
那麼以上在處理逆序對 i, j 一個在左邊一個在右邊這種情況的時候,就可以用上之前的MergeSort演算法,現在我們來回顧一下。
以上是MergSort的虛擬碼,它是輸入已排序的C和D,輸出是排序好的B。i,j分別控制C,D的元素,哪個元素小就把它加入到B中。那麼,這裡的C就是原問題中的左半部,D就是原問題的右半部分,當C[i] > D[j] 的時候,說明產生了逆序對,而C又是排序後的,所以i之後的數字都是大於D[j]的,所以對於D[j]所帶來的逆序對數目就是C陣列i到最後的元素個數,所以,我們可以在排序的基礎上計算出逆序對個數。把這一段話翻譯成虛擬碼就是如下。
這樣就完成了分治演算法對於逆序對的計算。時間複雜度是O(nlogn),比暴力搜尋快很多。文章開頭的問題你想通了嗎?
&nbs
- 分治演算法的基本步驟
- 逆序對計數是如何使用分治演算法來解決問題的
- 為什麼MergeSort排序法可以自然的算出逆序對數目
- 把輸入劃分成更小的子問題。
- 遞迴的治理子問題。
- 把子問題的解決方案組合到一起,形成原始問題的解決方案。
- 第1種就是逆序對 i 和 j 都位於陣列的左半部分,就是下標 i 和 j 是小於等於n/2的
- 第2種情況是逆序對 i 和 j 位於陣列的右半部分
- 第3種情況是逆序對 i 位於左半部分 j 位於右半部分,以上是虛擬碼。