《算法之道》精華 算法設計部分
- 本書作者鄒恆明,作者另有一本書《數據結構之弦》,以及《操作系統之哲學原理》都是很好的書
- 這本書可以算得上是深入淺出,文筆很好,作者添加了很多自己的思考
- 本文僅包括算法設計部分,算法分析略去,並沒有嚴格按照章節順序來記錄
附錄 算法隨想
- 有人喜歡遍歷,希望踏遍千山萬水,人生豐富多彩;有人一生貪婪,眼界不寬,及時行樂;有人註定窮搜,辛辛苦苦,收穫有限;有人善用時空均衡,用最少的時間辦最多的事情,十分精明;有人會分治,再難的問題也能解決;有人動態規劃,積少成多
第三章 分治與遞歸
- 生活中的例子:天平秤球以辨明次品;乘法運算;世界盃晉級賽;秦國合縱連橫
- 分治策略步驟:1,將問題分爲若干小問題;2,遞歸解決這些子問題;3,合併子問題的解答,得到大問題的解
- 標準分治策略的定義裏面包含遞歸:
T(n) = aT(n/b) + f(n)
- 遞歸式複雜度大師解法:
T(n) = aT(n/b) + f(n) = a^2T(n/b^2) + af(n/b) + f(n) = a^(log_b(n)) T(1) + a^(log_b(n-1) f(n/b^(log_b(n-1))) +...+a^2f(n/b^2) + af(n/b) + f(n) = O(n^log_b(a)) + sum(a^j f(n/b^j))|(j = 0...log_b(n-1))
- 前項爲遞歸樹最後一層節點數,後項爲遞歸樹各層分治過程分解與合併的代價
- f(n) < n^log_b(a)時,T(n) = O(n^log_b(a))
- f(n) > n^log_b(a) : T(n) = O(f(n))
- 算法題中常見分治例子:乘方運算、矩陣乘法、斐波那契數列的矩陣乘方解法、VLSI佈線
第四章 動態規劃
- 動態規劃是一種更有針對性的分治,分解得到的小問題很多重複,保存已經計算得到的結果可以免去重複計算
- 動態規劃每一步做出一個最優選擇,該最優選擇與子問題的最優解組合得到大問題的最優解
- 具體步驟:
- 證明問題的解決方案中包括一個選擇,選擇後剩下一個或多個子問題
- 設計遞歸描述方式,得到遞歸方程
- 證明對大問題的最優解包括對所有子問題的最優解
- 證明子問題之間重疊
- 兩個原則:最優子結構,重疊子問題
- 動態規劃的時間複雜度:全部子問題數量x選擇成本
- 算法題中常見動態規劃例子:最長公共子序列(最長遞增、最長遞減子序列,編輯距離)、最優二叉搜索樹
第五章 貪婪選擇思想
- 動態規劃在做出選擇之前,將所有選擇的結果做了比較,而如果選擇的時候不經過比較,而是直接選擇局部最優,就是貪婪
- 貪婪的目的只是找出一種可行解,在一定情況下找出的是最優解
- 貪婪與動態規劃相同,都是一種分治策略。但與動態規劃不同,貪婪將大問題分解爲一個,而不是多個子問題
- 具體步驟:
- 將原問題表述爲一個做出一個選擇,然後剩下唯一一個子問題的形式
- 證明所有的最優選擇裏面總有一個是貪婪選擇
- 證明貪婪選擇加上對剩下子問題的最優解導致大問題的最優解
- 貪婪的兩個原則:最優子結構(大問題的最優解包括小問題的最優解),貪婪選擇屬性
- 貪婪選擇屬性:每個小問題可以貪婪選擇獲得
- 算法題中常見貪婪例子:
- 揹包問題:財寶是否可以分割、每件財寶是否可以重複拿四個版本
- 教室課程規劃
- 最小生成樹
- Kruskal算法,每次加入一個不形成環的最小的邊,複雜度爲O(E log(V))
- Prime算法:每次加入距離最近的點,並降距,複雜度爲O(V^2),採用堆實現,可以達到O(E log(V))
- 霍夫曼編碼
第六章 隨機化思想
- 蒙特卡洛算法:大概率輸出正確答案,複雜度固定
- 常見隨機化算法例子:
- 素性測試:根據費馬小定理,若p爲素數,則
(a^p - a) % p == 0
;如果測試一百次都成立,則爲合數的概率只有2^(-100) - 矩陣乘積結果驗證:取隨機二進制01矢量z,有zAB = z(AB)
- 線性時間最小生成樹算法
- 素性測試:根據費馬小定理,若p爲素數,則