1. 程式人生 > >程式設計師需要知道的演算法

程式設計師需要知道的演算法

對於程式設計師來說演算法的重要性是毋庸置疑的,這就像從小學一年級就開始學習數學,指導研究生、博士生階段都有與數學有關的不同課程一樣。很多人也許會提出反對意見,指出現在做應用開發,使用JAVA的框架,進行資料處理無非就是CRUD,最重要的是要了解業務,掌握五花八門的WEB前端技術、事務處理、安全開發與防禦、資料處理……等等這些才是最重要的。“演算法,呵呵;我們不需要那麼“高深”的東西,工作中好像也用不到”。這是典型的“實用主義”思想,時髦一點可以給自己貼上了“極簡主義者”的標籤。

無論我們貼不貼標籤,演算法還是存在的,並且也是衡量一個程式設計師思維能力基礎。程式設計師需要了解,甚至掌握的演算法有那些呢?

演算法瞭解學習的多了,不是一件壞事。

資料結構 • 棧、佇列、連結串列

• 雜湊表,雜湊陣列
• 堆,優先佇列
雙端佇列
可並堆
左偏堆
• 二叉查詢樹
Treap
伸展樹
• 並查集
集合計數問題
二分圖的識別
• 平衡二叉樹
• 二叉排序樹
• 線段樹
一維線段樹
二維線段樹
• 樹狀陣列
一維樹狀陣列
N維樹狀陣列
• 字典樹
• 字尾陣列,字尾樹
• 塊狀連結串列
• 哈夫曼樹
• 桶,跳躍表
• Trie樹(靜態建樹、動態建樹)
• AC自動機
• LCA和RMQ問題
• KMP演算法

圖論 • 基本圖演算法圖

廣度優先遍歷
深度優先遍歷
拓撲排序
割邊割點
強連通分量
Tarjan演算法
雙連通分量
強連通分支及其縮點
圖的割邊和割點
最小割模型、網路流規約
2-SAT問題
歐拉回路
哈密頓迴路
• 最小生成樹
Prim演算法
Kruskal演算法(稀疏圖)
Sollin演算法
次小生成樹
第k小生成樹
最優比例生成樹
最小樹形圖
最小度限制生成樹
平面點的歐幾里德最小生成樹
平面點的曼哈頓最小生成樹
最小平衡生成樹
• 最短路徑
有向無環圖的最短路徑->拓撲排序
非負權值加權圖的最短路徑->Dijkstra演算法(可使用二叉堆優化)
含負權值加權圖的最短路徑->Bellmanford演算法
含負權值加權圖的最短路徑->Spfa演算法
(稠密帶負權圖中SPFA的效率並不如Bellman-Ford高)
全源最短路弗洛伊德演算法Floyd
全源最短路Johnson演算法
次短路徑
第k短路徑
差分約束系統
平面點對的最短路徑(優化)
雙標準限制最短路徑
• 最大流
增廣路->Ford-Fulkerson演算法
預推流
Dinic演算法
有上下界限制的最大流
節點有限制的網路流
無向圖最小割->Stoer-Wagner演算法
有向圖和無向圖的邊不交路徑
Ford-Fulkerson迭加演算法
含負費用的最小費用最大流
• 匹配
Hungary演算法
最小點覆蓋
最小路徑覆蓋
最大獨立集問題
二分圖最優完備匹配Kuhn-Munkras演算法
不帶權二分匹配:匈牙利演算法
帶權二分匹配:KM演算法
一般圖的最大基數匹配
一般圖的賦權匹配問題
• 拓撲排序
• 弦圖
• 穩定婚姻問題

搜尋

廣搜的狀態優化
利用M進位制數儲存狀態
轉化為串用hash表判重
按位壓縮儲存狀態
雙向廣搜
A*演算法
• 深搜的優化
位運算
剪枝
函式引數儘可能少
層數不易過大
雙向搜尋或者是輪換搜尋
IDA*演算法
• 記憶化搜尋

動態規劃

• 四邊形不等式理論
• 不完全狀態記錄
青蛙過河問題
利用區間dp
• 揹包類問題
0-1揹包,經典問題
無限揹包,經典問題
判定性揹包問題
帶附屬關係的揹包問題
+ -1揹包問題
雙揹包求最優值
構造三角形問題
帶上下界限制的揹包問題(012揹包)
• 線性的動態規劃問題
積木遊戲問題
決鬥(判定性問題)
圓的最大多邊形問題
統計單詞個數問題
棋盤分割
日程安排問題
最小逼近問題(求出兩數之比最接近某數/兩數之和等於某數等等)
方塊消除遊戲(某區間可以連續消去求最大效益)
資源分配問題
數字三角形問題
漂亮的列印
郵局問題與構造答案
最高積木問題
兩段連續和最大
2次冪和問題
N個數的最大M段子段和
交叉最大數問題
• 判定性問題的dp(如判定整除、判定可達性等)
模K問題的dp
特殊的模K問題,求最大(最小)模K的數
變換數問題
• 單調性優化的動態規劃
1-SUM問題
2-SUM問題
序列劃分問題(單調佇列優化)
• 剖分問題(多邊形剖分/石子合併/圓的剖分/乘積最大)
凸多邊形的三角剖分問題
乘積最大問題
多邊形遊戲(多邊形邊上是操作符,頂點有權值)
石子合併(N^3/N^2/NLogN各種優化)
• 貪心的動態規劃
最優裝載問題
部分揹包問題
乘船問題
貪心策略
雙機排程問題Johnson演算法
• 狀態dp
牛仔射擊問題(博弈類)
哈密頓路徑的狀態dp
兩支點天平平衡問題
一個有向圖的最接近二部圖
• 樹型dp
完美伺服器問題(每個節點有3種狀態)
小胖守皇宮問題
網路收費問題
樹中漫遊問題
樹上的博弈
樹的最大獨立集問題
樹的最大平衡值問題
構造樹的最小環

數論

• 中國剩餘定理
• 尤拉函式
• 歐幾里得定理
• 歐幾里德輾轉相除法求GCD(最大公約數)
• 擴充套件歐幾里得
• 大數分解與素數判定
• 佩爾方程
• 同餘定理(大數求餘)
• 素數測試
一千萬以內:篩選法
一千萬以外:米勒測試法
• 連分數逼近
• 因式分解
• 迴圈群生成元
• 素數與整除問題
• 進位制位.
• 同餘模運算

組合

• 排列組合
• 容斥原理
• 遞推關係和生成函式
• Polya計數法
Polya計數公式
Burnside定理
• N皇后構造解
• 幻方的構造
• 滿足一定條件的hamilton圈的構造
• Catalan數
• Stirling數
• 斐波拉契數
• 調和數
• 連分數
• MoBius反演
• 偏序關係理論
• 加法原理和乘法原理

計算

(幾何)
• 基本公式
叉乘
點乘
常見形狀的面積、周長、體積公式
座標離散化
• 線段
判斷兩線段(一直線、一線段)是否相交
求兩線段的交點
• 多邊形
判定凸多邊形,頂點按順時針或逆時針給出,(不)允許相鄰邊共線
判點在凸多邊形內或多邊形邊上,頂點按順時針或逆時針給出
判點在凸多邊形內,頂點按順時針或逆時針給出,在多邊形邊上返回0
判點在任意多邊形內,頂點按順時針或逆時針給出
判線段在任意多邊形內,頂點按順時針或逆時針給出,與邊界相交返回1
多邊形重心
多邊形切割(半平面交)
掃描線演算法
多邊形的核心
• 三角形
內心
外心
重心
垂心
費馬點
• 圓
判直線和圓相交,包括相切
判線段和圓相交,包括端點和相切
判圓和圓相交,包括相切
計算圓上到點p最近點,如p與圓心重合,返回p本身
計算直線與圓的交點,保證直線與圓有交點
計算線段與圓的交點可用這個函式後判點是否線上段上
計算圓與圓的交點,保證圓與圓有交點,圓心不重合
計算兩圓的內外公切線
計算線段到圓的切點
點集最小圓覆蓋
• 可檢視的建立
• 對踵點
• 經典問題
平面凸包
三維凸包
Delaunay剖分和Voronoi圖

計算

• 二分法
二分法求解單調函式相關知識
用矩陣加速的計算
• 迭代法
• 三分法
• 解線性方程組
LUP分解
高斯消元
• 解模線性方程組
• 定積分計算
• 多項式求根
• 週期性方程
• 線性規劃
• 快速傅立葉變換
• 隨機演算法
• 0/1分數規劃
• 三分法求解單峰(單谷)的極值
• 迭代逼近
• 矩陣法

博弈論
• 極大極小過程
• Nim問題