1. 程式人生 > >很重要很底層又很難的演算法-1

很重要很底層又很難的演算法-1

昨天下午閒著沒事刷公眾號,看到了一篇關於演算法的介紹,之前就見過那個課程,但是沒報名,昨天又看到了,一激動就報了名,報名之後看了前幾章,說的演算法都不懂啊,有的聽都沒聽說過(本人非計算機專業,培訓半年出道),後來想買都買了,不能浪費了,就在這準備把每章課程都copy過來,以後看不看吧,先放這。

課程背景

演算法在程式中扮演著非常重要的角色,有人將資料結構比喻為程式的骨架,將演算法比喻為程式的靈魂,這一點也不為過。正是因為這一點,很多朋友都立志要學好演算法,但是我常常看到各種抱怨,比如“看了半年《演算法》這本書,才看了幾十頁”,再比如“四年了,還是沒有啃完《演算法導論》”。出現這種情況的主要原因有兩個,其一是演算法紛繁複雜、知識點多,沒有一種放之四海而皆準的通用規則,很難一下子從總體上掌握全貌;其二是一些演算法雖然有常用的設計模式,但是不同的問題有不同的數學模型,需要設計好數學模型才能帶入演算法模式進行求解,然而設計數學模型對新手來說通常是個高高的門檻。

人們設計各種演算法的目的是解決現實中的問題,雖然各種演算法的實現五花八門,但是設計演算法卻有一些通用的方法或思想(也有的資料將其稱為演算法設計模式)。歸納起來,這些常見的演算法設計方法有迭代法、窮舉搜尋法、分支界限法(剪枝法)、遞推法、遞迴法、回溯法、分治法、貪婪法和動態規劃法等。

本課程選擇了三十多個簡單且實用的演算法例項,這些演算法例項基本覆蓋了各種演算法比賽中經常出現的題目以及生活中常見的一些有趣的演算法實現。每個演算法實現都將講解的側重點放在各種演算法的設計方法和思想在演算法中的體現,通過一個個演算法例子,來引導大家掌握常見的演算法設計思想。除此之外,在演算法實現的過程中,還會詳細介紹針對各個問題的建模過程,使讀者能夠舉一反三,學會如何將文字描述的問題抽象為演算法能夠使用的資料模型。總之,本課程的目的不是學會這些演算法,而是通過學習這些演算法的實現,掌握演算法設計的方法,以後遇到類似的問題,可以自己設計並實現解決問題的演算法。

課程大綱

前面介紹的各種演算法設計方法並不是孤立存在的,很多演算法最終的實現都是幾種演算法思想在一起融合後的產物。例如,窮舉搜尋法常常要結合遞迴和回溯操作實現窮舉遍歷,有時候還需要藉助分支界限法“剪掉”一些重複的分支或明顯不可能存在解的分支,目的是提高窮舉的效率;再比如很多讀者望而生畏的動態規劃法,其遞推關係的確定體現的就是遞推的思想;再再比如,迭代法通常結合分治的思想,使得每次迭代都能把大問題分解為一系列容易求解的小問題。有一些設計方法可以單獨成為一個主題,有些設計方法無法單獨列為一個主題進行講解,本課程前半部分根據常見的演算法題目,重點介紹迭代、窮舉和動態規劃三個主題,三個主題共計 18 個演算法例項,基本上涵蓋了上述所有演算法設計方法和思想的應用。本課程後半部分則通過 24 個有趣的演算法實現,讓大家理解演算法的重要性,但重點仍然是各種演算法設計思想的應用和如何設計適用於演算法的資料模型。

本課程的目的是培養大家解決實際問題的能力,每篇介紹一個演算法問題,通過對這個問題的分析和解決,鍛鍊大家針對問題設計資料模型,並應用合適演算法思想設計出解決問題的演算法實現的能力。

本課程分為七大部分,共計 43 篇。

第一部分(第 1-1 ~ 1-7 課):基礎

這部分內容共有 7 課,第 1-1 課為演算法基礎內容,介紹了將問題抽象成資料建模的常用方法。第 1-2 ~ 1-6 課介紹了 5 種常用的演算法設計思想(模式),分析了各種演算法模式的特點和使用時需要注意的要點,每種模式都用一 ~ 兩個具體的演算法做示例。第 1-7 課介紹了一些基礎演算法和技巧,比如排序、單鏈表逆序和用陣列儲存樹等小演算法,作為本課程開始之前的熱身或開胃菜。

第二部分(第 2.1 ~ 2.3 課):迭代和遞推

這部分內容通過 3 個在數學領域常用的數值分析方法,介紹了迭代思想在演算法設計中的應用,涉及的內容還包括瞭如何將數學公式或文字描述的遞推關係轉化為資料模型的方法。   

第三部分(第 3-1 ~ 3.7 課):窮舉搜尋

這部分內容通過 7 個不同的演算法例項,介紹了幾種常見的窮舉方法,比如線性數字類問題的窮舉方法、樹形空間的窮舉方法、棋盤類遊戲的常用窮舉方法以及複雜問題的多重窮舉和組合窮舉方法,重點介紹瞭如何設計與窮舉演算法相適應的資料模型,以及用合理的資料模型簡化演算法實現的技巧。

第四部分(第 4.1 ~ 4.7 課):動態規劃

這部分找了 7 個有趣的演算法,其中一些是演算法比賽中曾經出現的題目,一些是動態規劃的典型問題,既有簡單的線性(一維)動態規劃和二維動態規劃問題,也有凸多邊形的三角剖分、矩陣鏈乘這樣的熱點問題。動態規劃最重要的是劃分階段和確定狀態(確定遞推關係式),通過這些例子,可以瞭解如何建立問題對應的資料模型以及建立在資料模型上的遞推關係式。掌握這些方法,再遇到動態規劃類的問題時,就不會束手無策了。

第五部分(第 5.1 ~ 5.5 課):圖論

圖論即是各種演算法比賽中出題的“重災區”,也是現實生活中很多有趣演算法的理論基礎,這部分選擇了 5 個有趣的演算法,講解的重點仍然是各種演算法設計的思想和建立資料模型。

第六部分(第 6.1 ~ 6.6 課):遊戲中常用的演算法

這部分內容將介紹 6 個趣味演算法,介紹的內容包括決策樹、博弈樹和行為樹的搜尋演算法,涉及的內容包括窮舉、遞迴和分支界限法等演算法思想的應用。其中,棋類遊戲和俄羅斯方塊遊戲的演算法,都是非常經典的演算法,掌握這些經典的演算法思想,有助於讀者掌握各種解決各種決策、博弈類問題的解決方法。此外,這部分內容還介紹了經典的高效棋盤資料模型、估值函式和狀態 hash 演算法等程式程式碼設計技巧,學習完這些技巧將有助於開闊思維,提升程式碼能力。