程式設計師必須掌握哪些演算法?

CSDN學院發表於2016-10-28

來自知乎,原問題:程式設計師必須掌握哪些演算法?

一、SimonS(http://www.zhihu.com/people/simonshao)的回答:

我來緬懷一下當年OI和ACM的日子……題目都在 http://poj.org/ 上。

初期(校賽及省賽水題難度):

一.基本演算法:

列舉. (poj1753,poj2965)

貪心(poj1328,poj2109,poj2586)

遞迴和分治法.

遞推.

構造法.(poj3295)

模擬法.(poj1068,poj2632,poj1573,poj2993,poj2996)

二.圖演算法:

圖的深度優先遍歷和廣度優先遍歷.

最短路徑演算法(dijkstra,bellman-ford,floyd,heap+dijkstra)
(poj1860,poj3259,poj1062,poj2253,poj1125,poj2240)

最小生成樹演算法(prim,kruskal)
(poj1789,poj2485,poj1258,poj3026)

拓撲排序 (poj1094)

二分圖的最大匹配 (匈牙利演算法) (poj3041,poj3020)

最大流的增廣路演算法(KM演算法). (poj1459,poj3436)

三.資料結構.

串 (poj1035,poj3080,poj1936)

排序(快排、歸併排(與逆序數有關)、堆排) (poj2388,poj2299)

簡單並查集的應用.

雜湊表和二分查詢等高效查詢法(數的Hash,串的Hash)
(poj3349,poj3274,POJ2151,poj1840,poj2002,poj2503)

哈夫曼樹(poj3253)

trie樹(靜態建樹、動態建樹) (poj2513)

四.簡單搜尋

深度優先搜尋 (poj2488,poj3083,poj3009,poj1321,poj2251)

廣度優先搜尋(poj3278,poj1426,poj3126,poj3087.poj3414)

簡單搜尋技巧和剪枝(poj2531,poj1416,poj2676,1129)

五.動態規劃

揹包問題. (poj1837,poj1276)

型如下表的簡單DP(可參考lrj的書 page149):
E[j]=opt{D+w(i,j)} (poj3267,poj1836,poj1260,poj2533)
E[i,j]=opt{D[i-1,j]+xi,D[i,j-1]+yj,D[i-1][j-1]+zij} (最長公共子序列) (poj3176,poj1080,poj1159)
C[i,j]=w[i,j]+opt{C[i,k-1]+C[k,j]}.(最優二分檢索樹問題)

六.數學

組合數學:
1.加法原理和乘法原理.
2.排列組合.
3.遞推關係.
(POJ3252,poj1850,poj1019,poj1942)

數論.
1.素數與整除問題
2.進位制位.
3.同餘模運算.
(poj2635, poj3292,poj1845,poj2115)

計算方法.
1.二分法求解單調函式相關知識.(poj3273,poj3258,poj1905,poj3122)

七.計算幾何學.

幾何公式.

叉積和點積的運用(如線段相交的判定,點到線段的距離等). (poj2031,poj1039)

多邊型的簡單演算法(求面積)和相關判定(點在多邊型內,多邊型是否相交)
(poj1408,poj1584)

凸包. (poj2187,poj1113)

中級(校賽壓軸及省賽中等難度):

一.基本演算法:

C++的標準模版庫的應用. (poj3096,poj3007)

較為複雜的模擬題的訓練(poj3393,poj1472,poj3371,poj1027,poj2706)

二.圖演算法:

差分約束系統的建立和求解. (poj1201,poj2983)

最小費用最大流(poj2516,poj2516,poj2195)

雙連通分量(poj2942)

強連通分支及其縮點.(poj2186)

圖的割邊和割點(poj3352)

最小割模型、網路流規約(poj3308)

三.資料結構.

線段樹. (poj2528,poj2828,poj2777,poj2886,poj2750)

靜態二叉檢索樹. (poj2482,poj2352)

樹狀樹組(poj1195,poj3321)

RMQ. (poj3264,poj3368)

並查集的高階應用. (poj1703,2492)

KMP演算法. (poj1961,poj2406)

四.搜尋

最優化剪枝和可行性剪枝

搜尋的技巧和優化 (poj3411,poj1724)

記憶化搜尋(poj3373,poj1691)

五.動態規劃

較為複雜的動態規劃(如動態規劃解特別的旅行商TSP問題等)
(poj1191,poj1054,poj3280,poj2029,poj2948,poj1925,poj3034)

記錄狀態的動態規劃. (POJ3254,poj2411,poj1185)

樹型動態規劃(poj2057,poj1947,poj2486,poj3140)

六.數學

組合數學:
1.容斥原理.
2.抽屜原理.
3.置換群與Polya定理(poj1286,poj2409,poj3270,poj1026).
4.遞推關係和母函式.

數學.
1.高斯消元法(poj2947,poj1487, poj2065,poj1166,poj1222)
2.概率問題. (poj3071,poj3440)
3.GCD、擴充套件的歐幾里德(中國剩餘定理) (poj3101)

計算方法.
1.0/1分數規劃. (poj2976)
2.三分法求解單峰(單谷)的極值.
3.矩陣法(poj3150,poj3422,poj3070)
4.迭代逼近(poj3301)

隨機化演算法(poj3318,poj2454)

雜題(poj1870,poj3296,poj3286,poj1095)

七.計算幾何學.

座標離散化.

掃描線演算法(例如求矩形的面積和周長並,常和線段樹或堆一起使用)
(poj1765,poj1177,poj1151,poj3277,poj2280,poj3004)

多邊形的核心(半平面交)(poj3130,poj3335)

幾何工具的綜合應用.(poj1819,poj1066,poj2043,poj3227,poj2165,poj3429)

高階(regional中等難度):

一.基本演算法要求:

程式碼快速寫成,精簡但不失風格

(poj2525,poj1684,poj1421,poj1048,poj2050,poj3306)

保證正確性和高效性. poj3434

二.圖演算法:

度限制最小生成樹和第K最短路. (poj1639)

最短路,最小生成樹,二分圖,最大流問題的相關理論(主要是模型建立和求解)
(poj3155, poj2112,poj1966,poj3281,poj1087,poj2289,poj3216,poj2446

最優比率生成樹. (poj2728)

最小樹形圖(poj3164)

次小生成樹.

無向圖、有向圖的最小環

三.資料結構.

trie圖的建立和應用. (poj2778)

LCA和RMQ問題(LCA(最近公共祖先問題) 有離線演算法(並查集+dfs) 和 線上演算法(RMQ+dfs)).(poj1330)

雙端佇列和它的應用(維護一個單調的佇列,常常在動態規劃中起到優化狀態轉移的目的). (poj2823)

左偏樹(可合併堆).

字尾樹(非常有用的資料結構,也是賽區考題的熱點).(poj3415,poj3294)

四.搜尋

較麻煩的搜尋題目訓練(poj1069,poj3322,poj1475,poj1924,poj2049,poj3426)

廣搜的狀態優化:利用M進位制數儲存狀態、轉化為串用hash表判重、按位壓縮儲存狀態、雙向廣搜、A*演算法. (poj1768,poj1184,poj1872,poj1324,poj2046,poj1482)

深搜的優化:儘量用位運算、一定要加剪枝、函式引數儘可能少、層數不易過大、可以考慮雙向搜尋或者是輪換搜尋、IDA*演算法. (poj3131,poj2870,poj2286)

五.動態規劃

需要用資料結構優化的動態規劃.(poj2754,poj3378,poj3017)

四邊形不等式理論.

較難的狀態DP(poj3133)

六.數學

組合數學.
1.MoBius反演(poj2888,poj2154)
2.偏序關係理論.

博奕論.
1.極大極小過程(poj3317,poj1085)
2.Nim問題.

七.計算幾何學.

半平面求交(poj3384,poj2540)

可檢視的建立(poj2966)

點集最小圓覆蓋.

對踵點(poj2079)

八.綜合題.
(poj3109,poj1478,poj1462,poj2729,poj2048,poj3336,poj3315,poj2148,poj1263)

扯點建議:

如果你不是要死磕acm搞出成績來的話,多放點心思在資料結構上對以後的幫助會比較大,比如字串相關的字典樹、雜湊、自動機、字尾樹等等,而對腦力要求較高的比如博弈論和各種花式動態規劃(樹型DP、集合DP、插頭DP等等)就不用太關心了。

btw這些演算法和資料結構如果能精通的話,對你以後做資料探勘和機器學習是有極大幫助的。

二、慄先森(http://www.zhihu.com/people/li-xian-sen-7-72)的回答:

這個問答貼來自Quora(https://www.quora.com/What-algorithms-and-data-structures-should-any-software-engineer-know)。

演算法

圖搜尋 (廣度優先、深度優先)深度優先特別重要

排序

動態規劃

匹配演算法和網路流演算法

正規表示式和字串匹配

資料結構

圖 (樹尤其重要)

Map

棧/佇列

Tries | 字典樹

額外推薦

貪婪演算法

概率方法

近似演算法

上面是 Arjun Nayini 的推薦,下面是 Ken George 的推薦。

注:下面這個沒有特定優先順序

演算法:

三路劃分-快速排序

合併排序(更具擴充套件性,複雜度類似快速排序)

DF/BF 搜尋 (要知道使用場景)

Prim / Kruskal (最小生成樹)

Dijkstra (最短路徑演算法)

選擇演算法

資料結構

HashMap (真的要知道所有雜湊結構)

圖和樹(紅黑樹很好學) (red-black trees are good to learn)

堆(優先順序佇列)

棧/佇列(必須知道的基礎內容)

Tries | 字典樹

三、CSDN博主飄過的小牛(http://blog.csdn.net/niushuai666/article/details/6382225):

第一階段:練經典常用演算法,下面的每個演算法給我打上十到二十遍,同時自己精簡程式碼, 因為太常用,所以要練到寫時不用想,10-15分鐘內打完,甚至關掉顯示器都可以把程式打出來。

1.最短路(Floyd、Dijstra,BellmanFord)
2.最小生成樹(先寫個prim,kruscal要用並查集,不好寫)
3.大數(高精度)加減乘除
4.二分查詢. (程式碼可在五行以內)
5.叉乘、判線段相交、然後寫個凸包.
6.BFS、DFS,同時熟練hash表(要熟,要靈活,程式碼要簡)
7.數學上的有:輾轉相除(兩行內),線段交點、多角形面積公式.
8. 呼叫系統的qsort, 技巧很多,慢慢掌握.
9. 任意進位制間的轉換

第二階段:練習複雜一點,但也較常用的演算法。 如:

1.二分圖匹配(匈牙利),最小路徑覆蓋
2.網路流,最小費用流
3.線段樹
4.並查集
5.熟悉動態規劃的各個典型:LCS、最長遞增子串、三角剖分、記憶化dp
6.博弈類演算法:博弈樹,二進位制法等
7.最大團,最大獨立集
8.判斷點在多邊形內
9. 差分約束系統
10. 雙向廣度搜尋、A*演算法,最小耗散優先

相關的知識

圖論

路徑問題
0/1邊權最短路徑
BFS
非負邊權最短路徑(Dijkstra)
可以用Dijkstra解決問題的特徵
負邊權最短路徑
Bellman-Ford
Bellman-Ford的Yen-氏優化
差分約束系統
Floyd
廣義路徑問題
傳遞閉包
極小極大距離 / 極大極小距離
Euler Path / Tour
圈套圈演算法
混合圖的 Euler Path / Tour
Hamilton Path / Tour
特殊圖的Hamilton Path / Tour 構造
生成樹問題
最小生成樹
第k小生成樹
最優比率生成樹
0/1分數規劃
度限制生成樹
連通性問題
強大的DFS演算法
無向圖連通性
割點
割邊
二連通分支
有向圖連通性
強連通分支
2-SAT
最小點基
有向無環圖
拓撲排序
有向無環圖與動態規劃的關係
二分圖匹配問題
一般圖問題與二分圖問題的轉換思路
最大匹配
有向圖的最小路徑覆蓋
0 / 1矩陣的最小覆蓋
完備匹配
最優匹配
穩定婚姻
網路流問題
網路流模型的簡單特徵和與線性規劃的關係
最大流最小割定理
最大流問題
有上下界的最大流問題
迴圈流
最小費用最大流 / 最大費用最大流
弦圖的性質和判定

組合數學

解決組合數學問題時常用的思想 
    逼近 
    遞推 / 動態規劃 
概率問題 
    Polya定理

計算幾何 / 解析幾何

計算幾何的核心:叉積 / 面積 
解析幾何的主力:複數
基本形 
    點 
    直線,線段 
    多邊形
凸多邊形 / 凸包 
    凸包演算法的引進,捲包裹法 
Graham掃描法 
    水平序的引進,共線凸包的補丁
完美凸包演算法 
相關判定 
    兩直線相交 
    兩線段相交 
    點在任意多邊形內的判定 
    點在凸多邊形內的判定 
經典問題 
    最小外接圓 
        近似O(n)的最小外接圓演算法 
    點集直徑 
        旋轉卡殼,對踵點 
    多邊形的三角剖分

數學 / 數論

最大公約數
Euclid演算法
擴充套件的Euclid演算法
同餘方程 / 二元一次不定方程
同餘方程組
線性方程組
高斯消元法
解mod 2域上的線性方程組
整係數方程組的精確解法
矩陣
行列式的計算
利用矩陣乘法快速計算遞推關係
分數
分數樹
連分數逼近
數論計算
求N的約數個數
求phi(N)
求約數和
快速數論變換
……
素數問題
概率判素演算法
概率因子分解
資料結構
組織結構
二叉堆
左偏樹
二項樹
勝者樹
跳躍表
樣式圖示
斜堆
reap
統計結構
樹狀陣列
虛二叉樹
線段樹
矩形面積並
圓形面積並
關係結構
Hash表
並查集
路徑壓縮思想的應用
STL中的資料結構
vector
deque
set / map
動態規劃 / 記憶化搜尋
動態規劃和記憶化搜尋在思考方式上的區別
最長子序列系列問題
最長不下降子序列
最長公共子序列
最長公共不下降子序列
一類NP問題的動態規劃解法
樹型動態規劃
揹包問題
動態規劃的優化
四邊形不等式
函式的凸凹性
狀態設計
規劃方向
線性規劃
常用思想
二分 最小表示法

KMP Trie結構
字尾樹/字尾陣列 LCA/RMQ
有限狀態自動機理論
排序
選擇/冒泡 快速排序 堆排序 歸併排序
基數排序 拓撲排序 排序網路

初級:

一.基本演算法:
(1)列舉. (poj1753,poj2965) (2)貪心(poj1328,poj2109,poj2586)
(3)遞迴和分治法. (4)遞推.
(5)構造法.(poj3295) (6)模擬法.(poj1068,poj2632,poj1573,poj2993,poj2996)
二.圖演算法:
(1)圖的深度優先遍歷和廣度優先遍歷.
(2)最短路徑演算法(dijkstra,bellman-ford,floyd,heap+dijkstra)
(poj1860,poj3259,poj1062,poj2253,poj1125,poj2240)
(3)最小生成樹演算法(prim,kruskal)
(poj1789,poj2485,poj1258,poj3026)
(4)拓撲排序 (poj1094)
(5)二分圖的最大匹配 (匈牙利演算法) (poj3041,poj3020)
(6)最大流的增廣路演算法(KM演算法). (poj1459,poj3436)
三.資料結構.
(1)串 (poj1035,poj3080,poj1936)
(2)排序(快排、歸併排(與逆序數有關)、堆排) (poj2388,poj2299)
(3)簡單並查集的應用.
(4)雜湊表和二分查詢等高效查詢法(數的Hash,串的Hash)
(poj3349,poj3274,POJ2151,poj1840,poj2002,poj2503)
(5)哈夫曼樹(poj3253)
(6)堆
(7)trie樹(靜態建樹、動態建樹) (poj2513)
四.簡單搜尋
(1)深度優先搜尋 (poj2488,poj3083,poj3009,poj1321,poj2251)
(2)廣度優先搜尋(poj3278,poj1426,poj3126,poj3087.poj3414)
(3)簡單搜尋技巧和剪枝(poj2531,poj1416,poj2676,1129)
五.動態規劃
(1)揹包問題. (poj1837,poj1276)
(2)型如下表的簡單DP(可參考lrj的書 page149):
1.E[j]=opt{D+w(i,j)} (poj3267,poj1836,poj1260,poj2533)
2.E[i,j]=opt{D[i-1,j]+xi,D[i,j-1]+yj,D[i-1][j-1]+zij} (最長公共子序列)
(poj3176,poj1080,poj1159)
3.C[i,j]=w[i,j]+opt{C[i,k-1]+C[k,j]}.(最優二分檢索樹問題)
六.數學
(1)組合數學:
1.加法原理和乘法原理.
2.排列組合.
3.遞推關係.
(POJ3252,poj1850,poj1019,poj1942)
(2)數論.
1.素數與整除問題
2.進位制位.
3.同餘模運算.
(poj2635, poj3292,poj1845,poj2115)
(3)計算方法.
1.二分法求解單調函式相關知識.(poj3273,poj3258,poj1905,poj3122)
七.計算幾何學.
(1)幾何公式.
(2)叉積和點積的運用(如線段相交的判定,點到線段的距離等). (poj2031,poj1039)
(3)多邊型的簡單演算法(求面積)和相關判定(點在多邊型內,多邊型是否相交)
(poj1408,poj1584)
(4)凸包. (poj2187,poj1113)

中級:

一.基本演算法:
(1)C++的標準模版庫的應用. (poj3096,poj3007)
(2)較為複雜的模擬題的訓練(poj3393,poj1472,poj3371,poj1027,poj2706)
二.圖演算法:
(1)差分約束系統的建立和求解. (poj1201,poj2983)
(2)最小費用最大流(poj2516,poj2516,poj2195)
(3)雙連通分量(poj2942)
(4)強連通分支及其縮點.(poj2186)
(5)圖的割邊和割點(poj3352)
(6)最小割模型、網路流規約(poj3308, )
三.資料結構.
(1)線段樹. (poj2528,poj2828,poj2777,poj2886,poj2750)
(2)靜態二叉檢索樹. (poj2482,poj2352)
(3)樹狀樹組(poj1195,poj3321)
(4)RMQ. (poj3264,poj3368)
(5)並查集的高階應用. (poj1703,2492)
(6)KMP演算法. (poj1961,poj2406)
四.搜尋
(1)最優化剪枝和可行性剪枝
(2)搜尋的技巧和優化 (poj3411,poj1724)
(3)記憶化搜尋(poj3373,poj1691)
五.動態規劃
(1)較為複雜的動態規劃(如動態規劃解特別的施行商問題等)
(poj1191,poj1054,poj3280,poj2029,poj2948,poj1925,poj3034)
(2)記錄狀態的動態規劃. (POJ3254,poj2411,poj1185)
(3)樹型動態規劃(poj2057,poj1947,poj2486,poj3140)
六.數學
(1)組合數學:
1.容斥原理.
2.抽屜原理.
3.置換群與Polya定理(poj1286,poj2409,poj3270,poj1026).
4.遞推關係和母函式.
(2)數學.
1.高斯消元法(poj2947,poj1487, poj2065,poj1166,poj1222)
2.概率問題. (poj3071,poj3440)
3.GCD、擴充套件的歐幾里德(中國剩餘定理) (poj3101)
(3)計算方法.
1.0/1分數規劃. (poj2976)
2.三分法求解單峰(單谷)的極值.
3.矩陣法(poj3150,poj3422,poj3070)
4.迭代逼近(poj3301)
(4)隨機化演算法(poj3318,poj2454)
(5)雜題.
(poj1870,poj3296,poj3286,poj1095)
七.計算幾何學.
(1)座標離散化.
(2)掃描線演算法(例如求矩形的面積和周長並,常和線段樹或堆一起使用).
(poj1765,poj1177,poj1151,poj3277,poj2280,poj3004)
(3)多邊形的核心(半平面交)(poj3130,poj3335)
(4)幾何工具的綜合應用.(poj1819,poj1066,poj2043,poj3227,poj2165,poj3429)

高階:

一.基本演算法要求:
(1)程式碼快速寫成,精簡但不失風格
(poj2525,poj1684,poj1421,poj1048,poj2050,poj3306)
(2)保證正確性和高效性. poj3434
二.圖演算法:
(1)度限制最小生成樹和第K最短路. (poj1639)
(2)最短路,最小生成樹,二分圖,最大流問題的相關理論(主要是模型建立和求解)
(poj3155, poj2112,poj1966,poj3281,poj1087,poj2289,poj3216,poj2446
(3)最優比率生成樹. (poj2728)
(4)最小樹形圖(poj3164)
(5)次小生成樹.
(6)無向圖、有向圖的最小環
三.資料結構.
(1)trie圖的建立和應用. (poj2778)
(2)LCA和RMQ問題(LCA(最近公共祖先問題) 有離線演算法(並查集+dfs) 和線上演算法
(RMQ+dfs)).(poj1330)
(3)雙端佇列和它的應用(維護一個單調的佇列,常常在動態規劃中起到優化狀態轉移的
目的). (poj2823)
(4)左偏樹(可合併堆).
(5)字尾樹(非常有用的資料結構,也是賽區考題的熱點).
(poj3415,poj3294)
四.搜尋
(1)較麻煩的搜尋題目訓練(poj1069,poj3322,poj1475,poj1924,poj2049,poj3426)
(2)廣搜的狀態優化:利用M進位制數儲存狀態、轉化為串用hash表判重、按位壓縮儲存狀態、雙向廣搜、A*演算法. (poj1768,poj1184,poj1872,poj1324,poj2046,poj1482)
(3)深搜的優化:儘量用位運算、一定要加剪枝、函式引數儘可能少、層數不易過大、可以考慮雙向搜尋或者是輪換搜尋、IDA*演算法. (poj3131,poj2870,poj2286)
五.動態規劃
(1)需要用資料結構優化的動態規劃.
(poj2754,poj3378,poj3017)
(2)四邊形不等式理論.
(3)較難的狀態DP(poj3133)
六.數學
(1)組合數學.
1.MoBius反演(poj2888,poj2154)
2.偏序關係理論.
(2)博奕論.
1.極大極小過程(poj3317,poj1085)
2.Nim問題.
七.計算幾何學.
(1)半平面求交(poj3384,poj2540)
(2)可檢視的建立(poj2966)
(3)點集最小圓覆蓋.
(4)對踵點(poj2079)
八.綜合題. (poj3109,poj1478,poj1462,poj2729,poj2048,poj3336,poj3315,poj2148,poj1263)

相關文章