
巴爾加瓦
本書示例豐富,圖文並茂,以簡明易懂的方式闡釋了算法,旨在幫助程序員在日常項目中更好地利用算法爲軟件開發助力。前三章介紹算法基礎,包括二分查找、大O表示法、兩種基本的數據結構以及遞歸等。餘下的篇幅將主要介紹應用廣泛的算法,具體內容包括:面對具體問題時的解決技巧,比如何時採用貪婪算法或動態規劃;散列表的應用;圖算法;K最近鄰算法。本書適合所有程序員、計算機專業相關師生以及對算法感興趣的讀者。
相當不錯的一本入門級算法書。 曾看到過一句話,算法是“科技變革的底層引擎”。 想想自己過去十多年的程序員生涯,最後悔的就是沒有編寫過比較深刻,驚豔且實用的算法用在生產環境中,將很多精力放在了設計模式,架構設計,分佈式設計上,後來做了技術管理後,就更加不能接觸到算法了,爲此遺憾不已。 如今拿起這本書,看到了熟悉的數據結構,數組,鏈表,散列表,集合等等,還看到了很多使用的排序規則,快速排序,二叉樹搜索,紅黑樹等等。本是一些十分專業的概念,而作者圖文並茂地講解了很多基礎知識,讓讀者引人入勝於其中。 思考一下當今生活,很多算法的應用。 1,我們聽歌,看視頻,APP總會根據我們經常聽的歌曲或者電影推薦給我們類似的曲目或電影,其背後就是K鄰近算法。 2,我們開車,導航會推薦幾條建議路線,其背後就是以Dijkstra(迪傑斯特拉)算法爲基礎的各種算法。 3,外賣平臺,網約車派單等都是通過背後的啓發式優化算法如蟻羣算法,遺傳算法等來實現的。 其他如人工智能,AI機器人就更加不用說了,難度就在於各種算法。如果說要給未來年輕人給點學習和就業上的建議,如果對數學感興趣,那就去研究算法。各種學校研究機構,大廠,AI公司,機器人公司以及各行各業,養豬,種植,市政規劃,物流,鐵路航空等等都是急需這樣的人才的,還是那句話:學好數理化,走遍天下都不怕,尤其是數學,重中之重啊!
本書圖文並茂,用通俗易懂語言介紹什麼是算法的基礎知識。常言道,一圖抵百字,翻過本書後,不服都不行?就像讀兒童時期連環畫一樣,讀它居然初步認識了計算機算法的一些基本知識,非常喜歡! 常言還說,不要只埋頭拉車不看路,本書說白了,不僅僅是看路,而且是看你一條路走是又快又好。瞭解它,當然本書希望是幫助設計人員通過好的途徑,可令計算機獲得最佳優選擇算法。 本是介紹的就是其中的一些原理。例如,“算法的速度指的並非時間,而是操作數的增速。 ❑ 談論算法的速度時,我們說的是隨着輸入的增加,其運行時間將以什麼樣的速度增加。 ❑ 算法的運行時間用大O表示法表示。 ❑ O(log n)比O(n)快,當需要搜索的元素越多時,前者比後者快得越多”。 ............. 簡言之,它雖然說看起來簡單,實際上它提供給普通讀者的,還真有些像“內行看門道 ,外行看熱鬧”高招。本書語言不多,道理深。因爲它本身也是水很涼很深,在裏面遊不一定舒服,除非是哪些會玩的,不得不學或者強壯....呵呵! 好在作者非常厚道,他也告訴讀者那些內容不必讀。 本書關鍵字就是搜索!這本小冊子中的作業居然還附有答案!
算法使人聰明,本書使人愚蠢! 首先,結構混亂. 講算法,裏面又插入數據結構的內容, 講數據結構,又不講齊全, 講不下去了,就一句話:後面你就知道了. 其次,概念不清. 第二章講遞歸,把循環和遞歸攪拌不清, 講不清楚了,又加入了棧的內容. 棧講的糊里糊塗,就結束了. 突然提出一句:爲什麼要學習遞歸? 因爲有些語言沒有循環. 正如書友評論: 現在還有哪個語言沒有循環的? 第三,舉例混亂 本書號稱圖解, 除了老祖母的箱子之類,和算法沒多大關係, 而且增加理解難度的插圖以外, 其餘圖解,就是手繪內存圖 而且寫到0,都要用φ, 特別容易和專用符號混淆, 和任何一個學校的板書有什麼區別? 圖解的意義何在? 本來對算法和Python有點了解 本書只用3章就讓我徹底混亂. 它讓我想起了開培訓班圈錢的“水師” 大水漫灌,還情真意切的說: 我知道的太多了,想全都告訴你們, 只可惜長8張嘴都不夠 既然,8張嘴都說不清,何不shut up !
瑕不掩瑜 我會這樣定義一本我眼中的好書:深入淺出、關聯豐富以及與我當下的認知水平相當。 這本小書的最大優點就在推理過程交代清楚。一步一步、爲什麼這麼想、這麼走,都給你描畫得一清二楚。換言之,它是按照事物發展的邏輯順序進行內容構建的,看得就很過癮,像一本推理小說。 舉例而言,它會在介紹完 SHA 算法後立刻介紹局部敏感的散列算法,在我剛在前一節中提出問題,如果我不想一點變動就讓哈希值完全不同,那麼應如何處理?它在下一節立刻墊上了,用 Simhash。這種邏輯上的完備與層層遞進,就減少了很多理解成本。有時候你覺得理解困難,就是因爲中間有步驟被抽去了,例如你在數學書裏經常看到的:顯然可得、易證得。 所以這是一本看起來很過癮的小書。細嚼慢嚥,給你剝出來最精華的內核。 但有一個錯誤我覺得是不該發生也不能被容忍的。在第七章,狄克斯特拉算法中,有明顯錯誤。作者指出,狄只適用於有向無環圖。而這是不正確的,事實上,只要沒有負權邊就可以。我在這裏思路銜接不上,因爲從算法實現中推不出作者言之鑿鑿的結果,最後經外部確認,才發現是作者出錯。 看得出,作者對這個算法本身也理解不透徹。很多地方,沒有講透。例如在頂點選取上,爲什麼是選取當下可選點中,值最小的那個?因爲在沒有負權邊的圖中,它是已經被固定了的,因爲要走其他任何一點再回到該頂點,都會造成值更大。而更新每個頂點的最小值,就是這個算法的核心,也是最機智、最動人、最美的地方。 也就是動態規劃。前序的最優子結構,後面都可以直接拿來用,而且只要沒有負權邊,就滿足無後效性的條件。但是作者既沒有講到上面那句缺失的話,讓這個問題在我腦子裏多思考了大半天,直到在另一本《我的第一本算法書》中才得到啓發;也沒有聯繫動態規劃或者貪婪算法。或許略難,但是可以提一提,一帶而過。 對了,這本書建議結合《我的第一本算法書》一起看,微信讀書裏也有,另外建議下載配套 app 一起使用方便理解,app 叫做 Algorithms。 因爲這本書出版好些年了,這種硬傷還沒有被更正,就讓我不能接受。但是整體上瑕不掩瑜,是很好的入門書。況且它也給到學有餘力的同學繼續探索的空間。我非常喜歡他常常在篇末寫的,如果你對這個話題感興趣,歡迎你繼續沿着某某算法的腳步朝裏面研究。我非常喜歡這種引導。 最後,閱讀算法書請配合力扣。我之所以會盛讚這本書,認爲作者很多地方講透了,就是因爲很多章節我一看完,或者看了一半,就忍不住想開力扣開始刷相關標籤的題目。動規、二分尤甚。這就是他把我講明白了的最好說明。 最後的最後提醒自己,多找這類書看就夠了,不要看雞零狗碎的算法公衆號,除非你能聯繫上作者能進一步溝通交流,不然直接讀書纔是最有效率的方式。出版書通常作了更好的排序工作,而且因爲編輯的存在,錯誤也更少。 公號的錯別字就夠喝一壺,作者的自身理解不夠,你看文章有如猜謎,更加難懂。
《算法圖解》拆解 作者:[美]巴爾加瓦 一、一句話概括 學習算法不是爲了背代碼,而是掌握一組解決問題的思維模型:怎樣縮小搜索範圍、怎樣選擇數據結構、怎樣拆分問題,以及怎樣在時間、空間和解的質量之間作出權衡。 二、核心邏輯 全書按照“基礎—策略—應用—延伸”的路線展開: 1. 基礎:二分查找、大O表示法、數組、鏈表、遞歸和棧。2. 核心策略:分而治之、快速排序、散列表和圖搜索。3. 問題求解:最短路徑、貪婪算法、動態規劃和K最近鄰。4. 延伸方向:樹、倒排索引、並行計算、MapReduce、概率型數據結構、密碼學和線性規劃。 學習路徑可以概括爲: 先判斷數據規模 → 選擇合適的數據結構 → 識別問題類型 → 選擇算法策略 → 分析時間與空間複雜度 → 用測試驗證邊界條件 本書用大量圖示降低算法門檻,重點在直覺和應用,而不是嚴格數學證明。 三、核心內容 1. 算法是解決問題的步驟,複雜度描述增長速度 兩個算法都能得到正確答案,但數據規模擴大後,運行時間可能差異巨大。 大O表示法關注輸入規模增長時,操作次數怎樣變化。 常見覆雜度包括: O(1):常數時間;O(log n):對數時間;O(n):線性時間;O(n log n):高效排序常見覆雜度;O(n²):雙重遍歷;O(2ⁿ)和O(n!):組合爆炸。 大O通常忽略常數項和低階項,適合比較增長趨勢,而不是精確預測運行秒數。 2. 二分查找通過不斷排除一半數據提高效率 在有序數據中,二分查找先檢查中間元素: 如果目標更小,排除右半部分;如果目標更大,排除左半部分;然後在剩餘一半中重複。 每一步都把搜索範圍減半,因此複雜度是O(log n)。 它的前提是數據有序,並且能夠高效訪問中間位置。若數據未排序,還要考慮排序成本。 3. 數組和鏈表代表兩種存儲權衡 數組把元素連續存放,因此通過索引讀取通常很快。 鏈表的節點可以分散存放,每個節點保存下一個節點的位置,因此插入和刪除更靈活,但隨機訪問較慢。 簡單比較: 數組擅長按位置讀取;鏈表擅長在已知位置附近插入和刪除;數組通常具有更好的緩存局部性;鏈表需要額外指針空間;實際語言中的動態數組能夠兼顧多種操作。 數據結構選擇應根據最頻繁的操作,而不是抽象地判斷誰更好。 4. 選擇排序直觀展示“尋找+刪除”的成本 選擇排序每次從未排序元素中找出最小值,再放到結果中的正確位置。 尋找最小值需要遍歷剩餘數據,整個過程重複多次,因此時間複雜度是O(n²)。 選擇排序實現簡單,卻不適合大規模數據。 它的教學意義在於幫助讀者理解:一個容易描述的步驟反覆執行,可能產生平方級成本。 5. 遞歸讓函數用更小的問題解決原問題 遞歸函數會調用自身,把當前問題縮小。 每個遞歸都需要兩個部分: 基線條件:何時停止;遞歸條件:怎樣把問題縮小並繼續調用。 缺少正確基線條件會導致無限遞歸或棧溢出。 遞歸適合表達樹、分治和回溯等結構,但不一定比循環更快。其優勢往往是代碼更接近問題定義。 6. 調用棧保存函數執行狀態 函數調用時,系統需要保存局部變量、返回地址和當前執行位置,這些信息進入調用棧。 棧遵循“後進先出”: 新調用壓入棧頂;函數完成後從棧頂彈出;程序回到上一級調用。 遞歸層數太深會佔用大量棧空間。因此,分析算法時不僅要看時間,也要看遞歸帶來的空間成本。 7. 分而治之把複雜問題拆成相似子問題 分而治之通常包含三步: 1)找到最簡單的基線情況;2)把原問題拆成更小的同類問題;3)合併子問題的結果。 快速排序、歸併排序和二分查找都體現了這種思想。 分而治之的關鍵,是拆分後子問題更小,並且解決子問題能夠直接支持原問題。 8. 快速排序依賴基準值和分區 快速排序選擇一個基準值,把其他元素分成小於基準和大於基準的兩組,然後分別遞歸排序。 平均情況下,其時間複雜度爲O(n log n)。 如果每次基準選擇極差,分區嚴重不平衡,最壞情況會退化爲O(n²)。 實際實現通常通過隨機基準、三數取中或小數組切換其他排序等方式降低風險。 9. 散列表用計算位置實現快速查找 散列函數把鍵映射到數組位置,使插入、查找和刪除在平均情況下接近O(1)。 散列表可用於: 字典和映射;緩存;去重;頻次統計;檢查是否訪問過;建立對象索引。 不同鍵可能映射到同一位置,這叫散列衝突。衝突處理和負載因子會影響實際性能。 散列表依賴良好的散列函數和容量管理,並不保證每次操作都嚴格是O(1)。 10. 圖用於表示關係網絡 圖由節點和邊組成。 邊可以是有向或無向,也可以帶有權重。社交關係、道路、依賴、通信和任務流程都可以表示爲圖。 圖通常使用: 鄰接表;鄰接矩陣。 稀疏圖更適合鄰接表,邊非常密集或需要快速檢查節點是否直接相連時,鄰接矩陣可能更合適。 11. 廣度優先搜索尋找無權圖的最短路徑 廣度優先搜索從起點開始,先訪問距離一條邊的節點,再訪問距離兩條邊的節點。 它使用隊列保持“先進先出”順序,因此第一次到達某個節點時,路徑通常就是邊數最少的路徑。 BFS可用於: 查找最近關係;無權圖最短路徑;層級遍歷;判斷可達性;網絡廣播。 必須記錄已經訪問的節點,否則在包含環的圖中可能無限重複。 12. 狄克斯特拉算法處理非負權圖的最短路徑 當每條邊成本不同,單純按邊數搜索不再適用。 狄克斯特拉算法反覆選擇當前成本最低的未處理節點,並更新經過該節點到達鄰居的成本。 它適用於邊權非負的圖。 如果存在負權邊,已經確定的最短距離仍可能被後續路徑降低,算法就會失效。此時需要Bellman-Ford等其他方法。 13. 貪婪算法每一步選擇當前最優 貪婪算法不回頭修改之前的選擇,因此通常實現簡單、速度快。 在教室調度等問題中,選擇最早結束的活動能夠得到全局最優。 但在揹包等問題中,局部最優不一定組成全局最優。 使用貪婪策略時,應判斷問題是否具有貪婪選擇性質,並儘可能證明結果,而不是因爲策略直觀就默認正確。 14. NP完全問題提醒我們接受近似解 某些組合問題的可能方案隨規模快速增長,目前沒有已知的高效通用精確算法。 判斷一個問題可能屬於NP完全問題的線索包括: 需要嘗試大量組合;很難找到有效縮小搜索空間的方法;與旅行商、集合覆蓋等經典問題相似;輸入稍微增大,精確搜索就無法承受。 面對這類問題,可以使用: 近似算法;貪婪方法;啓發式搜索;隨機算法;限定問題規模;接受時間與質量權衡。 知道何時停止追求精確解,是重要的工程能力。 15. 動態規劃保存重複子問題的結果 動態規劃適用於可以拆成相互重疊子問題,並具有最優子結構的問題。 它通常使用表格保存較小問題的最優結果,避免反覆計算。 揹包問題中,表格可以按物品和容量逐步構建;最長公共子序列或子串也可以使用二維狀態表。 動態規劃的關鍵是正確設計: 狀態表示;狀態轉移;初始條件;計算順序;最終答案位置。 找到狀態定義,往往比寫循環更困難。 16. K最近鄰依靠相似樣本進行預測 K最近鄰算法找到距離新樣本最近的K個已知樣本,再根據它們的類別投票或數值平均。 它可以用於分類、迴歸和簡單推薦。 關鍵問題包括: 怎樣定義距離;特徵是否需要標準化;K值如何選擇;無關特徵是否干擾相似性;數據量大時查詢是否太慢。 KNN幾乎沒有顯式訓練過程,但預測時需要保存並搜索大量數據。 17. 推薦系統的基礎是定義“相似” 用KNN構建推薦時,可以根據用戶評分、行爲或物品屬性計算相似度。 如果兩個用戶偏好相近,可以用其中一人的選擇推測另一人可能喜歡什麼。 但現實推薦系統還需要處理: 數據稀疏;新用戶和新物品;熱門偏差;相似度尺度;興趣變化;計算效率;多樣性與探索。 簡單KNN適合建立推薦直覺,大規模系統通常還會使用矩陣分解、深度模型和在線反饋。 18. 樹、倒排索引和概率型結構擴展算法工具箱 書末介紹多種後續學習方向: 樹和二叉搜索樹用於層級數據與有序查找;倒排索引用於搜索引擎,從詞定位文檔;布隆過濾器以少量內存判斷元素可能是否存在;HyperLogLog近似統計不同元素數量;局部敏感散列用於快速尋找相似項。 這些方法展示了工程中的常見權衡:允許少量誤差,可以換取顯著的速度或空間優勢。 19. 並行算法和MapReduce處理大規模數據 當單機無法高效處理任務時,可以把數據和計算拆到多個節點。 MapReduce把工作分爲: Map:對數據分片執行相同處理;Reduce:匯總中間結果。 分佈式計算不僅要考慮算法本身,還要處理網絡、數據移動、節點故障和負載均衡。 能夠並行不代表一定更快,小規模任務的通信成本可能超過計算收益。 20. 密碼學算法建立數字信任 SHA等哈希算法把任意輸入轉換爲固定長度摘要,可用於完整性檢查和密碼存儲等場景。 Diffie-Hellman允許通信雙方在公開信道上協商共享密鑰。 密碼學安全依賴經過廣泛檢驗的算法和正確實現,不能自行設計“看起來很複雜”的加密方案。 算法知識不僅用於提高速度,也用於建立安全邊界。 21. 本書強調直覺,但不是完整算法教材 本書通過圖解和簡單Python代碼幫助初學者建立直覺,適合第一次系統接觸算法。 爲了易懂,它簡化了部分證明、邊界條件和工程實現。 讀完後還需要繼續學習: 更嚴格的複雜度分析;正確性證明;更多數據結構;圖的高級算法;實際語言庫的實現;緩存與硬件性能;併發和分佈式系統。 圖解是入口,而不是算法學習的終點。 四、本書最值得關注的核心觀點 本書最值得關注的觀點是: 選擇算法之前,先識別問題結構。 如果數據有序,可以考慮二分查找;如果問題是關係網絡,可以建圖;如果要尋找無權最短路徑,可以用BFS;如果包含非負成本,可以考慮狄克斯特拉;如果子問題重複,可以使用動態規劃;如果精確求解成本過高,則應考慮貪婪或近似方法。 真正的算法能力不是記住更多代碼,而是能夠把現實問題映射到熟悉結構,並理解這種映射所依賴的前提。 五、一段話總結 《算法圖解》以圖示和Python示例介紹二分查找、大O複雜度、數組與鏈表、遞歸與調用棧、分而治之、快速排序、散列表、圖、廣度優先搜索、狄克斯特拉算法、貪婪算法、動態規劃和K最近鄰,並延伸到樹、倒排索引、MapReduce、布隆過濾器、HyperLogLog和密碼學。全書的重點不是背誦實現,而是識別問題結構:有序數據可以縮小一半搜索範圍,關係問題可以建圖,重複子問題可以保存結果,規模過大的組合問題則應接受近似解。雖然本書爲了易懂簡化了部分證明和工程細節,但它清楚展示了算法思維的核心——在正確性、時間、空間和解的質量之間作出有根據的選擇。
遇到這樣一本有趣的算法書籍後,你就會意識到,學習算法也可以像看喜歡的小說一樣令人沉醉。 未學習過算法的,讀完本書,以後的算法學習之路將會一帆風順。對於熟悉算法的同學,本書也可以加深你的理解,有些晦澀難懂的概念和動態規劃等等,根本無需死記硬背。當你想到某個算法時,你腦海中,就會自動繪製出一幅相關景象了。 後悔這麼晚遇到它。
很好的一本算法入門書,不過封面標榜的像小說一樣有趣,應該寫在《算法之美》上更適合。 算法跟哲學有點兒類似,言簡意賅又包羅萬象,由些許個例高度抽象出來的規律,可以無限延伸擴展,都引發深度思考。不同在於,哲學由於其天生的多面性、不確定性,容易培養成流氓性質的詭辯思維,案例古今中外比比皆是。算法雖然沒有像數學一樣的精確性,但大體上是向準確性靠攏的,準確或者近似準確。也正因爲這一點,算法才得以在各行各業大行其道,這也是社會物質條件越來越便利,物聯網必然興起的理論基礎。反向來看,透過現象看實質,從社會治理,政策調控,經濟規劃,工業設計等方面看,其背後都有一些若隱若現的極其相似的東西,這些相似的東西,應該也可以稱之爲算法吧。
算法真的很有意思,看到停不下來。這本書文字與圖片結合,講的很通俗,很容易理解。比較感興趣的幾個算法:動態規劃,廣度優先,Dijkstra加權圖最短路徑,分治法。學習算法重在思考,對問題思考的過程比解決問題本身更重要。好的算法能夠優雅地解決複雜的問題,讓人歎爲觀止。
這是我看過的最好的關於算法的拋磚引玉之作。能把算法這種連專業人員都倍感困難的內容講得像讀故事一樣通俗易懂的書實屬罕見。本書圖文並茂,平易近人,是算法初學者的首選佳作。從未學過算法的,看過此書,今後算法的學習將一凡風順。學過算法的,此書將讓你不再懼怕算法,和算法做朋友。
《算法圖解》這本書給我的最大感受是:它不是在教我“多厲害的算法”,而是在教我“如何正確地看待算法”。 在閱讀這本書之前,我對算法的印象更多停留在“面試必備”“刷題工具”“難而且枯燥”。算法像是一道道孤立的題目,記住解法就算過關。但《算法圖解》用一種極其直觀、循序漸進的方式,把算法從“抽象符號”拉回到了“解決問題的工具”這個本質上。 一、圖解的力量:把“想不通”變成“看得懂” 這本書最大的特點就是“圖多字少”。無論是二分查找、廣度優先搜索,還是狄克斯特拉算法,作者都會先畫出一步一步發生了什麼,而不是一上來就給公式或僞代碼。 這種方式讓我第一次意識到: 算法難,並不是因爲它複雜,而是因爲我們沒看到過程。 當搜索過程、路徑選擇、狀態變化被畫出來之後,很多“爲什麼要這麼做”的問題,其實會自己消失。 二、算法不是技巧,而是思維方式 《算法圖解》反覆強調一個核心思想:算法的價值,在於減少無謂的嘗試。 比如: 二分查找,本質是“每一步都排除一半不可能” BFS,是“層級推進,保證最先到達的一定最短” Dijkstra,是“每次做一個永遠不會後悔的選擇” 這讓我開始用算法的視角重新看待日常問題:不是“我能不能做出來”,而是“有沒有辦法更快排除錯誤路徑”。 三、對時間複雜度的直覺被真正建立起來了 以前看到 O(n)、O(n log n),更多是一種“背概念”的狀態。而這本書通過對比操作次數、畫增長曲線的方式,讓我真正建立起了直覺。 我開始能在寫代碼時自然地問自己: 這個循環會跑幾次? 數據量翻十倍會發生什麼? 這個解法是不是在“重複做無意義的事”? 這是一個從“能寫代碼”到“寫得更聰明”的轉折點。 四、它降低了算法的心理門檻 《算法圖解》沒有試圖一次性講完所有高級算法,而是非常剋制地只選擇最核心、最常用的那一部分。 這反而讓我意識到: 算法不是一座必須一口氣爬完的山,而是一條可以慢慢走的路。 掌握好搜索、排序、圖、動態規劃的基本思想,就已經能解決大量真實問題,而不是爲了“算法很牛”而學算法。 五、讀完之後的意識轉變 讀完這本書後,我最大的變化不是“我記住了多少算法”,而是: 不再下意識地迴避算法問題 遇到複雜邏輯,開始主動拆解狀態和選擇 更願意問“有沒有更優的思路”,而不是“先湊個能跑的” 這本書更像是一位耐心的引路人,而不是一個站在高處的考官。