圖靈技術演算法群第1期:《演算法圖解》讀書筆記

威玲旺卡發表於2017-08-28

書名:《演算法圖解》(原文書名:《Grokking Algorithms》,作者:Aditya Y. Bhargava,譯者:袁國忠) 購買連結:中譯版 , 原版

簡短點評:愛因斯坦說,“如果你不能把它解釋給你外婆聽,那麼你就沒有弄明白。”(You do not really understand something unless you can explain it to your grandmother.)用來解釋這本用心的書再合適不過。真的弄明白了才能把文縐縐的理論說成大白話。這是一本鼓勵人學習計算機演算法的好書。

前言:這篇是「威玲旺卡Aileen」在讀過中譯版的《Grokking Algorithms》後的筆記。轉載筆記不用註明我,但請註明原書作者和譯者,及標註連結到購買連結,謝謝。

第1章:二分查詢(Binary Search)+ 時間複雜度O

二分查詢:對數時間 O(log n) ,前提:有序
簡單查詢 (Simple Search):線性時間O(n)

第2章:選擇排序(Selection Search)+ 陣列(Array)+ 連結串列(List)

陣列:讀取 O(1) 插入 O(n) 刪除 O(n)
連結串列:讀取 O(n) 插入 O(1) 刪除 O(1)
混合資料:連結串列陣列
選擇排序:O(n^2)

第3章:遞迴(Recursion)+棧(Stack)

迴圈都可以用遞迴取代
基線條件(Base Case)+ 遞迴條件(Recursive Case)
呼叫棧(Call Stack) FILO

第4章:快速排序(Quick Sort)+分而治之(Divide & Conquer)

D&C:關鍵1. 找出基準條件 2. 每次遞迴縮小問題規模
D&C:不是一種解決演算法,而是一種解決思路
擴充:歐幾里德演算法
快速排序:選擇一個基準值(Pivot),分成兩個分割槽(Partition),對分割槽進行快速排序
擴充:歸納證明。需要基線條件,歸納條件,就如同遞迴
執行時間:快速排序的平均情況是O(n log n),最糟糕是O(n^2)
擴充:合併排序(Merge Sort)的執行時間是O(n log n)
O的常量影響:合併排序的常量比快速排序大。所以在平均情況下,快速排序更快。

第5章:雜湊表,a.k.a. 雜湊表(Hash Table)

雜湊表所有操作時間都是常量時間O(1)
Python dict() 或 {}
應用場合:模擬對映,防止重複給flag,快取/記住資料
衝突(Collision):指產生的相同雜湊函式地址,解決方法是加連結串列(鏈地址法),拖慢雜湊表速度是缺點
防止衝突:1. 及時調整長度(Resizing),保持較低的填充因子(<0.7)2. 用好的雜湊函式(SHA)

第6章:廣度優先搜尋(Breadth-First-Search,BFS)+ 圖(有向/無向)+ 佇列(Queue)

例子:在FB找芒果銷售商,從一度關係到二度關係類推
Python deque()
複雜度:O(V+E)V指頂點(vertices),E指邊(edges),O(V+E)是因為佇列需要檢查每個頂點,而搜尋需要過每條邊。
因為檢查順序很關鍵,所以需要先進先出的佇列,最終才能得到最短距離。
最短序列問題 -> 圖建模 -> 用廣度優先搜尋解決

第7章:狄克斯特拉演算法(Dijkstra's Algorithm)+ 加權圖(Weighted Graph)

演算法過程:1. 找出最便宜的節點; 2. 遍歷鄰居,如果有前往它們的更短路徑,就更新開銷; 3. 重複,直到找過每個節點 ;4. 計算最終路徑。
只用於有向無環圖(Directed Acyclic Graph, DAG)
負權邊用貝爾曼-福德演算法(Bellman-Ford Algthorithm)
3個雜湊表實現Dijkstra:1. Graph 2. Costs 3. Parents

第8章:貪婪演算法 (Greedy Algorithm)+ NP完全問題(NP-completeness)+ 集合 (Set)

貪婪演算法:一直取最優解
Python set()
集合覆蓋問題:廣播電臺企圖覆蓋所有州,複雜度O(2^n),可以用近似演算法求近似最優解
旅行商問題(Travelling Salesman Problem):複雜度O(n!)
NP完全:求近似解更可行
如何識別可能的NP完全:1. 元素少時很快,速度隨著元素變多而速度迅猛下跌 2. 所有組合問題 3. 不能用D&C降解 4. 設計序列,如旅行商問題(Travelling salesman problem),設計集合,如廣播臺集合問題 5. 可以轉換為集合覆蓋問題或者旅行商問題的都是NP完全問題。

第9章:動態規劃 (Dynamic Programming, DP)

動態規劃用於求在約束條件下的最優解,在問題可分解為彼此獨立且離散的子問題時。
揹包問題
動態規劃的解決一定涉及網格,單元格的值就是要優化的值,每個單元格都是一個自問題,所以應該考慮如何將問題分成子問題。這有助於找到網格的座標軸。
例:找最大公共字串和最大公共序列
應用:git diff,levenshtein距離,Microsoft Word行斷
計算動態規劃方案的公式按情況不同而變化

第10章:K最近鄰(K Nearest Neighbor, KNN)

分類就是編組,迴歸就是預測
除了用歐幾里得距離作為距離公式,還有餘弦相似度(Cosine Similarity)
應用:OCR,郵件分類用到了樸素貝葉斯分類(Naive Bayes Classifier),預測股票
選取的特徵關係KNN的成敗

第11章:展望

二叉查詢樹(Binary Tree):操作平均情況複雜度O(log n)。相關:B樹,紅黑樹,堆,伸展樹。
反向索引,建立搜尋引擎
傅立葉變換,時域->頻域
並行演算法。MapReduce,工具Apache Hadoop,對映函式Map,歸併函式Reduce
布隆過濾器,一種概率型資料結構,可能錯報,但不可能漏報
Hyperloglog,類似布隆過濾器
SHA演算法,應用相同檔案/檢查密碼
Simhash區域性敏感,SHA區域性不敏感
Diffie-Hellman,RSA金鑰,公鑰+私鑰
線性規劃,圖是線性規劃的一個子集

複雜度集合:

二分查詢:O(log n)
簡單查詢:O(n)
選擇排序:O(n^2)
合併排序:O(n log n)
快速排序:O(n log n)
旅行商問題:O(n!)
二叉查詢樹:O(log n)
雜湊表一項操作:O(1)
集合覆蓋問題:O(2^n)
廣度優先搜尋:O(V+E)

最後更新時間:2017年8月

相關文章