A comprehensive algorithms review, summarizing the key topics: divide and conquer, graph algorithms, dynamic programming, linear programming, P vs NP, reductions, and more.
Divide and Conquer
Master theorem:
for some constants (a>0) , (b>1) ,and (d ≥0) , then
d is the exponent of the time complexity of the non-recursive part (i.e., the work done outside each recursive call).
Proof: analyze the total work in the recursion tree
FFT
Graph Algorithms
DFS
1 | EXPLORE(G, v): |
running time: O(|V|+|E|)
SCC (Strongly Connected Components)
1 | Input: 有向图 G = (V, E) |
running time: O(|V|+|E|)
Dijkstra
1 | **Input**: 图 G, 边权 ℓ, 起点 s |
Bellman-Ford
1 | **Input**: 图 G, 边权 ℓ, 起点 s(无负环) |
running time: O(|V| * |E|)
Shortest Paths in a DAG
A topological order is a linear ordering of the vertices of a directed acyclic graph (DAG) in which, for every edge (u, v), u comes before v.1
2
3
4
5
6
7
8
9
10
11
12Input: DAG G, 边权 ℓ, 起点 s
Output: 最短距离 dist[]
1. for each u ∈ V:
2. dist[u] = ∞; prev[u] = nil
3. dist[s] = 0
4. L = 拓扑排序(G) # 按线性序排列节点
5. for each u ∈ L (按序处理):
6. for each 边 (u, v) ∈ E:
7. if dist[v] > dist[u] + ℓ(u, v):
8. dist[v] = dist[u] + ℓ(u, v)
9. prev[v] = u
running time: O(|V| + |E|)
MST (Minimum Spanning Tree)
1 | Kruskal(G) |
Cut property: for any cut (S, V-S) of a graph G, the minimum-weight edge crossing between S and V-S must belong to some MST.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23并查集
# 初始化单元素集合
makeset(x):
1. π[x] = x # 父指针
2. rank[x] = 0 # 秩
# 查找根(带路径压缩)
find(x):
1. if x ≠ π[x]:
2. π[x] = find(π[x]) # 递归压缩路径
3. return π[x]
# 合并集合(按秩合并)
union(x,y):
1. rx = find(x), ry = find(y)
2. if rx == ry: return
3. if rank[rx] > rank[ry]:
4. π[ry] = rx
5. else:
6. π[rx] = ry
7. if rank[rx] == rank[ry]:
8. rank[ry]++
Dynamic Programming
Dynamic Programming
- Core idea: break the problem into overlapping subproblems and store the subproblem solutions to avoid redundant computation.
- Key steps:
- Define the subproblems
- Set up the recurrence (state transition equation)
- Determine the evaluation order (bottom-up or memoized search)
- Applications:
- Longest Increasing Subsequence (LIS): length of the LIS ending at j
- Edit distance: the minimum cost of aligning two strings,
- Knapsack:
- Knapsack with repetition:
- 0/1 knapsack:
- Matrix chain multiplication: minimize the number of multiplications,
- Traveling Salesman Problem (TSP): C(S,j) is the shortest path that passes through the set S and ends at j; complexity O(n^2 2^n).
- Independent set on a tree: maximum independent set size
LIS (Longest Increasing Subsequence)
1 | Input: 序列 a[1..n] |
running time: O(n^2)
LCS (Longest Common Subsequence)
1 | Input: 序列 a[1..n], b[1..m] |
running time: O(n*m)
0/1 Knapsack
1 | Input: 物品重量 w[1..n], 价值 v[1..n], 容量 W |
Linear Programming
MAX Flow
1 | FORD-FULKERSON(G, s, t): |
The idea behind Ford-Fulkerson:
- Build the residual graph: residual capacity of a forward edge = c_e - f_e, capacity of a backward edge = f_e
- Iteratively search for augmenting paths: use BFS/DFS to find an s→t path in the residual graph
- Update the flow: push an amount equal to the minimum residual capacity along the path
- Complexity: O(|V|·|E|²)
Max Flow-Min Cut theorem: the maximum flow equals the minimum cut, i.e., in a flow network, the maximum flow from the source to the sink equals the minimum total capacity of the edges cut when the network is split into two parts.
Bipartite matching can be solved by reducing it to max flow: turn the bipartite graph into a flow network, connect the source to the left-side vertices, connect the right-side vertices to the sink, and give every edge capacity 1.
Simplex
Dual LP

P vs NP
Class P:
- Decision problems that can be solved by a polynomial-time algorithm
- Time complexity O(n^k), where k is a constant
Class NP:
- Decision problems for which, given a solution, its correctness can be verified in polynomial time
- Nondeterministic Polynomial time
NP-Complete problems:
- Problems that belong to NP
- Every problem in NP can be reduced to them in polynomial time
- If any NP-Complete problem has a polynomial-time algorithm, then P = NP
NP-Complete
Search Problem: given an instance I and a solution checker C(I,S) (polynomial-time verification), find a solution S
Search problems are equivalent to NP problems.
| Problem | Description | Counterpart in P |
|---|---|---|
| 3SAT | Satisfiability with three-literal clauses | 2SAT (two-literal clauses) |
| TSP | Traveling salesman problem (minimum-cost tour) | Minimum spanning tree |
| LONGEST PATH | Longest simple path in a graph | Shortest path |
| 3D MATCHING | Three-set matching (boy-girl-pet) | Bipartite matching |
| KNAPSACK | Knapsack (integer weights/values) | Unit-weight knapsack (dynamic programming) |
| INDEPENDENT SET | Independent set in a graph (no two chosen vertices adjacent) | Independent set on a tree |
| ILP | Integer linear programming | Linear programming (simplex method) |
Reductions
A -> B (A is no harder than B, A <= B)
Key points:
- Instance transformation
- Solution transformation (including passing along “no solution”)
- Both done in polynomial time
For non-search problems, only the instance transformation is needed.
Reduction chain analysis: 3SAT → INDEPENDENT SET → VERTEX COVER → CLIQUE
1. 3SAT → INDEPENDENT SET
- Goal: reduce Boolean satisfiability (3SAT) to the independent set problem.
Steps:
a. Instance transformation:- For a 3SAT formula with k clauses, construct a graph G:
- Each clause becomes a triangle (3 vertices), whose vertices represent the literals in the clause (e.g. ).
- Add conflict edges: if two literals are complementary (e.g. x and
), connect them across all triangles.
- Set the target independent set size g = k (the number of clauses).
Example: the formula
→ two triangles: , and add the edges
b. Solution transformation:
- If an independent set of size g exists, then exactly one vertex is chosen from each triangle (the conflict edges guarantee that complementary literals are never both chosen).
- Set the chosen literals to true (e.g. if x is chosen then x=true; if
is chosen then x=false
- For a 3SAT formula with k clauses, construct a graph G:
- Key insight:
Choosing the independent set = picking one true literal per clause, with a globally consistent assignment.
2. INDEPENDENT SET → VERTEX COVER
- Goal: reduce independent set to the vertex cover problem.
Steps:
a. Instance transformation:- Given a graph G=(V,E) and independent set target g, use the very same graph G
- Set the vertex cover target b = |V| - g (e.g. |V|=5, g=2 → b=3
b. Solution transformation:
- If a vertex cover C of size b exists, then is an independent set of size g.
(because C covers every edge → there are no edges inside ) - If an independent set S of size g exists, then is a vertex cover of size b.
- Key insight:
Independent set and vertex cover are complementary problems:
3. VERTEX COVER → CLIQUE
- Goal: reduce vertex cover to the clique problem.
Steps:
a. Instance transformation:- Given a graph G=(V,E) and vertex cover target b, construct its complement graph
- Set the clique target g = |V| - b (e.g. |V|=4, b=1 → g=3
b. Solution transformation:
- If
has a clique K of size g, then is a vertex cover of G of size b.
(since K is a complete subgraph in→ it has no edges in G → covers every edge of G) - If G has a vertex cover C of size b, then
is a clique of size g in .
c. Passing along “no solution”:
- If
has no clique of size g, then G has no vertex cover of size b.
- Given a graph G=(V,E) and vertex cover target b, construct its complement graph
Key insight:
The complement of a vertex cover is a clique in the complement graph:


Other Algorithms
Euclid’s Algorithm
1 | Euclid(a, b) |
For any positive integers a and b ,the extended Euclid algorithm returns integers x , y ,and d such that go
RSA
1 | 1. 随机选择大素数 p, q → 计算 N = p * q |
The correctness of RSA rests on Euler’s theorem:
If gcd(m, n) = 1, then m^φ(n) ≡ 1 (mod n)
Prime Testing
Fermat’s little theorem: if p is prime and a is any integer, then a^(p-1) ≡ 1 (mod p)1
2
3
4
5
6
7primality2(N)
// Input: positive integer N
// Output: yes/no
1. Pick positive integers a1, a2, ..., ak<N at random
2. if ai^{N-1} ≡ 1 (mod N ) for all i=1,2, ..., k
then return yes
3. else return no.
Pr(primality2 returns yes when N is prime) = 1
Pr(primality2 returns yes when N is not prime) ≤ 1 / 2^k
Translated from the Chinese original.

