Section 5 · Revision

Algorithms formula sheet

Recurrences, complexities, standard counts and exam rules for every Algorithms topic on one page.

Full notes Section test

Asymptotic complexity

Notation Meaning
f=O(g)f = O(g) f(n)≤c g(n)f(n) \le c\,g(n) for all n≥n0n \ge n_0
f=Ω(g)f = \Omega(g) f(n)≥c g(n)f(n) \ge c\,g(n) for all n≥n0n \ge n_0
f=Θ(g)f = \Theta(g) both of the above
f=o(g)f = o(g) f/g→0f/g \to 0
f=ω(g)f = \omega(g) f/g→∞f/g \to \infty

Growth order: 1<log⁡log⁡n<log⁡n<(log⁡n)k<n<n<nlog⁡n<n2<nlog⁡n<2n<3n<n!<nn1 < \log\log n < \log n < (\log n)^k < \sqrt{n} < n < n\log n < n^2 < n^{\log n} < 2^n < 3^n < n! < n^n.

  • Compare two functions by comparing their logs: log⁡(nlog⁡n)=log⁡2n\log(n^{\log n}) = \log^2 n, log⁡(2n)=n\log(2^n) = n.
  • alog⁡bn=nlog⁡baa^{\log_b n} = n^{\log_b a}. log⁡(n!)=Θ(nlog⁡n)\log(n!) = \Theta(n\log n). n!=o(nn)n! = o(n^n), 2n=o(n!)2^n = o(n!).
  • (2nn)=Θ(4n/n)\binom{2n}{n} = \Theta(4^n/\sqrt{n}). Hn=∑1/i=ln⁡n+O(1)H_n = \sum 1/i = \ln n + O(1).
  • 2f=O(2g)2^{f} = O(2^{g}) does NOT follow from f=O(g)f = O(g).

Master theorem for T(n)=aT(n/b)+f(n)T(n) = aT(n/b) + f(n), with p=log⁡bap = \log_b a:

Case Condition Result
1 f=O(np−ϵ)f = O(n^{p - \epsilon}) Θ(np)\Theta(n^{p})
2 f=Θ(nplog⁡kn)f = \Theta(n^{p}\log^k n), k≥0k \ge 0 Θ(nplog⁡k+1n)\Theta(n^{p}\log^{k+1} n)
2, k=−1k = -1 f=Θ(np/log⁡n)f = \Theta(n^{p}/\log n) Θ(nplog⁡log⁡n)\Theta(n^{p}\log\log n)
2, k<−1k < -1 f=Θ(nplog⁡kn)f = \Theta(n^{p}\log^k n) Θ(np)\Theta(n^{p})
3 f=Ω(np+ϵ)f = \Omega(n^{p + \epsilon}) and af(n/b)≤cf(n)af(n/b) \le cf(n), c<1c < 1 Θ(f(n))\Theta(f(n))

Other recurrences:

Recurrence Solution
T(n)=T(n−1)+nT(n) = T(n-1) + n Θ(n2)\Theta(n^2)
T(n)=2T(n−1)+1T(n) = 2T(n-1) + 1 Θ(2n)\Theta(2^n)
T(n)=T(n/2)+nT(n) = T(n/2) + n Θ(n)\Theta(n)
T(n)=T(n/3)+T(2n/3)+nT(n) = T(n/3) + T(2n/3) + n Θ(nlog⁡n)\Theta(n\log n)
T(n)=T(n/5)+T(7n/10)+nT(n) = T(n/5) + T(7n/10) + n Θ(n)\Theta(n) (fractions sum below 1)
T(n)=2T(n)+log⁡nT(n) = 2T(\sqrt{n}) + \log n Θ(log⁡nlog⁡log⁡n)\Theta(\log n \log\log n)
T(n)=T(n)+1T(n) = T(\sqrt{n}) + 1 Θ(log⁡log⁡n)\Theta(\log\log n)
T(n)=n T(n)+nT(n) = \sqrt{n}\,T(\sqrt{n}) + n Θ(nlog⁡log⁡n)\Theta(n\log\log n)
  • n\sqrt{n} recurrences: substitute n=2mn = 2^m, then S(m)=T(2m)S(m) = T(2^m).

Loop counting:

Loop Iterations
i = 1; i <= n; i *= 2 ⌊log⁡2n⌋+1\lfloor \log_2 n \rfloor + 1
i = 2; i <= n; i = i*i Θ(log⁡log⁡n)\Theta(\log\log n)
inner j = 1; j <= i with outer i *= 2 2n−12n - 1 total, Θ(n)\Theta(n)
inner j += i for i = 1..n ∑⌊n/i⌋=Θ(nlog⁡n)\sum \lfloor n/i \rfloor = \Theta(n\log n)
inner j *= 2 up to ii, outer i = 1..n Θ(nlog⁡n)\Theta(n\log n)

Searching and sorting

Algorithm Best Average Worst Space Stable In place
Bubble (early exit) nn n2n^2 n2n^2 11 yes yes
Insertion nn n2n^2 n2n^2 11 yes yes
Selection n2n^2 n2n^2 n2n^2 11 no yes
Merge nlog⁡nn\log n nlog⁡nn\log n nlog⁡nn\log n nn yes no
Quick nlog⁡nn\log n nlog⁡nn\log n n2n^2 log⁡n\log n to nn no yes
Heap nlog⁡nn\log n nlog⁡nn\log n nlog⁡nn\log n 11 no yes
Counting n+kn + k n+kn + k n+kn + k n+kn + k yes no
Radix (dd digits, base bb) d(n+b)d(n + b) d(n+b)d(n + b) d(n+b)d(n + b) n+bn + b yes no
  • Comparison sort lower bound: ⌈log⁡2n!⌉\lceil \log_2 n! \rceil comparisons, Ω(nlog⁡n)\Omega(n\log n).
  • Insertion sort: shifts = inversions II; time Θ(n+I)\Theta(n + I). Max inversions n(n−1)/2n(n-1)/2.
  • Selection sort: at most n−1n - 1 swaps.
  • Merge of lists of sizes mm, nn: min min⁡(m,n)\min(m, n) comparisons, max m+n−1m + n - 1.
  • Merge sort worst case comparisons on n=2kn = 2^k: nlog⁡2n−n+1n\log_2 n - n + 1.
  • Quicksort worst case: sorted or reverse sorted input with first or last pivot, and all-equal keys with Lomuto. Comparisons then n(n−1)/2n(n-1)/2.
  • Quicksort recursing on the smaller part first: stack O(log⁡n)O(\log n).
  • Radix sort of nn keys in range 00 to nc−1n^c - 1 with base nn: Θ(cn)\Theta(cn).
  • Counting sort: prefix sums C[i]=C[i] = number of keys ≤i\le i; scan input right to left for stability.

Selection and order statistics:

Task Cost
Min or max n−1n - 1 comparisons
Min and max together (pairs) ⌈3n/2⌉−2\lceil 3n/2 \rceil - 2
Second smallest (tournament) n+⌈log⁡2n⌉−2n + \lceil \log_2 n \rceil - 2
kk-th smallest, quickselect Θ(n)\Theta(n) average, Θ(n2)\Theta(n^2) worst
kk-th smallest, median of medians (groups of 5) Θ(n)\Theta(n) worst
Median of medians with groups of 3 Θ(nlog⁡n)\Theta(n\log n)

Binary search:

  • Worst case probes on nn sorted keys: ⌊log⁡2n⌋+1\lfloor \log_2 n \rfloor + 1.
  • n=2k−1n = 2^k - 1: average successful probes =1n∑d=1kd 2d−1= \frac{1}{n}\sum_{d=1}^{k} d\,2^{d-1}.
  • Loop while lo < hi, A[mid] < x then lo = mid + 1 else hi = mid: returns first index with A[i]≥xA[i] \ge x (lower bound). With <= it returns first index with A[i]>xA[i] > x (count of elements ≤x\le x).

Hashing

Quantity Value (load factor α=n/m\alpha = n/m)
Chaining, unsuccessful search Θ(1+α)\Theta(1 + \alpha)
Chaining, successful search 1+α/21 + \alpha/2 approx.
Chaining, worst case search Θ(n)\Theta(n)
Open addressing, unsuccessful (uniform hashing) ≤1/(1−α)\le 1/(1 - \alpha) probes
Open addressing, successful ≤1αln⁡11−α\le \frac{1}{\alpha}\ln\frac{1}{1-\alpha}
Expected keys in a slot α\alpha
Expected colliding pairs (universal) ≤(n2)/m\le \binom{n}{2}/m
Probing Probe ii Distinct sequences Problem
Linear (h(k)+i) mod m(h(k) + i) \bmod m mm primary clustering
Quadratic (h(k)+c1i+c2i2) mod m(h(k) + c_1 i + c_2 i^2) \bmod m mm secondary clustering
Double (h1(k)+i h2(k)) mod m(h_1(k) + i\,h_2(k)) \bmod m Θ(m2)\Theta(m^2) none of the above
  • Double hashing visits all slots iff gcd⁡(h2(k),m)=1\gcd(h_2(k), m) = 1: use mm prime, or m=2rm = 2^r with h2h_2 odd. h2(k)≠0h_2(k) \ne 0 always.
  • Quadratic probing with i2i^2 can miss slots: i2 mod 8∈{0,1,4}i^2 \bmod 8 \in \{0, 1, 4\}. With prime mm and α≤1/2\alpha \le 1/2 an empty slot is always found.
  • Linear probing: an empty slot right after a run of rr full slots is filled next with probability (r+1)/m(r + 1)/m.
  • Deletion in open addressing: mark as deleted (tombstone), never empty, or later searches stop early.
  • Universal family: Pr⁡h[h(x)=h(y)]≤1/m\Pr_h[h(x) = h(y)] \le 1/m for every x≠yx \ne y. Example: ha,b(k)=((ak+b) mod p) mod mh_{a,b}(k) = ((ak + b) \bmod p) \bmod m, pp prime, 1≤a<p1 \le a < p, 0≤b<p0 \le b < p.

Greedy algorithms

Problem Greedy rule Time
Activity selection earliest finish time O(nlog⁡n)O(n\log n)
Interval partitioning (rooms) sort by start; answer = max overlap O(nlog⁡n)O(n\log n)
Fractional knapsack highest value/weight first O(nlog⁡n)O(n\log n)
Huffman coding merge two smallest O(nlog⁡n)O(n\log n)
Optimal merge pattern merge two smallest files O(nlog⁡n)O(n\log n)
Job sequencing with deadlines highest profit, latest free slot O(n2)O(n^2) or O(nlog⁡n)O(n\log n)
Min sum of completion times shortest job first O(nlog⁡n)O(n\log n)
Min weighted completion decreasing wj/pjw_j/p_j O(nlog⁡n)O(n\log n)
Min max lateness earliest deadline first O(nlog⁡n)O(n\log n)
MST Kruskal, Prim see graphs
  • Greedy fails: 0/1 knapsack, coin change for non-canonical systems ({1,7,10}\{1, 7, 10\}, amount 15: greedy 6, optimum 3), activity selection by shortest or earliest start.
  • Huffman on nn symbols: n−1n - 1 merges, n−1n - 1 internal nodes, max code length n−1n - 1 (Fibonacci frequencies).
  • Huffman total bits =∑fiℓi== \sum f_i \ell_i = sum of all internal node weights.
  • Optimal merge cost = sum of all intermediate merged sizes.

Dynamic programming

Use DP when there are optimal substructure and overlapping subproblems.

Problem Recurrence Time Space
LCS match: c[i−1][j−1]+1c[i-1][j-1] + 1; else max⁡(c[i−1][j],c[i][j−1])\max(c[i-1][j], c[i][j-1]) O(mn)O(mn) O(mn)O(mn), O(min⁡(m,n))O(\min(m,n)) for length only
Edit distance min⁡(d[i−1][j]+1,d[i][j−1]+1,d[i−1][j−1]+[ai≠bj])\min(d[i-1][j] + 1, d[i][j-1] + 1, d[i-1][j-1] + [a_i \ne b_j]) O(mn)O(mn) O(mn)O(mn)
LIS L[i]=1+max⁡j<i,aj<aiL[j]L[i] = 1 + \max_{j < i, a_j < a_i} L[j] O(n2)O(n^2), O(nlog⁡n)O(n\log n) with tails O(n)O(n)
0/1 knapsack max⁡(K[i−1][w],vi+K[i−1][w−wi])\max(K[i-1][w], v_i + K[i-1][w - w_i]) O(nW)O(nW) pseudo-polynomial O(nW)O(nW)
Subset sum S[i][s]=S[i−1][s]∨S[i−1][s−ai]S[i][s] = S[i-1][s] \lor S[i-1][s - a_i] O(nW)O(nW) O(W)O(W)
Coin change (ways) N[s]+=N[s−c]N[s] \mathrel{+}= N[s - c], coins in outer loop O(kS)O(kS) O(S)O(S)
Rod cutting rn=max⁡k(pk+rn−k)r_n = \max_k (p_k + r_{n-k}) O(n2)O(n^2) O(n)O(n)
Matrix chain min⁡k(m[i][k]+m[k+1][j]+pi−1pkpj)\min_k (m[i][k] + m[k+1][j] + p_{i-1}p_kp_j) O(n3)O(n^3) O(n2)O(n^2)
Optimal BST min⁡r(e[i][r−1]+e[r+1][j])+w(i,j)\min_r (e[i][r-1] + e[r+1][j]) + w(i, j) O(n3)O(n^3), O(n2)O(n^2) Knuth O(n2)O(n^2)

Standard counts:

Count Value
Parenthesisations of nn matrices Catalan Cn−1=1n(2n−2n−1)C_{n-1} = \frac{1}{n}\binom{2n-2}{n-1}: 1, 1, 2, 5, 14, 42
BSTs on nn keys CnC_n: 1, 2, 5, 14, 42 for n=1..5n = 1..5
Monotone lattice paths to (a,b)(a, b) (a+ba)\binom{a + b}{a}
Naive recursive Fibonacci calls for FnF_n 2Fn+1−12F_{n+1} - 1
  • Any k2+1k^2 + 1 distinct numbers contain a monotone subsequence of length k+1k + 1 (Erdos-Szekeres).
  • Coin change ways: coin loop outside counts combinations; amount loop outside counts ordered sequences.

Divide and conquer

Algorithm Recurrence Time
Merge sort 2T(n/2)+n2T(n/2) + n Θ(nlog⁡n)\Theta(n\log n)
Max subarray (D&C) 2T(n/2)+n2T(n/2) + n Θ(nlog⁡n)\Theta(n\log n); Kadane Θ(n)\Theta(n)
Counting inversions 2T(n/2)+n2T(n/2) + n Θ(nlog⁡n)\Theta(n\log n)
Closest pair 2T(n/2)+n2T(n/2) + n (presorted) Θ(nlog⁡n)\Theta(n\log n)
Closest pair, re-sort strip each call 2T(n/2)+nlog⁡n2T(n/2) + n\log n Θ(nlog⁡2n)\Theta(n\log^2 n)
Karatsuba 3T(n/2)+n3T(n/2) + n Θ(nlog⁡23)=Θ(n1.585)\Theta(n^{\log_2 3}) = \Theta(n^{1.585})
Strassen 7T(n/2)+n27T(n/2) + n^2 Θ(nlog⁡27)=Θ(n2.807)\Theta(n^{\log_2 7}) = \Theta(n^{2.807})
Fast power xnx^n T(n/2)+1T(n/2) + 1 Θ(log⁡n)\Theta(\log n)
Power with two recursive calls 2T(n/2)+12T(n/2) + 1 Θ(n)\Theta(n)
Min and max (halves) 2T(n/2)+22T(n/2) + 2 3n/2−23n/2 - 2 comparisons
  • Strassen: 7 products, 18 additions of n/2n/2 blocks. Scalar multiplications 7log⁡2n7^{\log_2 n}; additions A(n)=7A(n/2)+18(n/2)2A(n) = 7A(n/2) + 18(n/2)^2.
  • A b×bb \times b block scheme with kk products runs in Θ(nlog⁡bk)\Theta(n^{\log_b k}) (when log⁡bk>2\log_b k > 2); compare exponents.
  • Closest pair strip: compare each point with at most the next 7 in yy order.

Graph traversals, MST and shortest paths

Algorithm Time (adjacency list) Notes
BFS, DFS O(V+E)O(V + E) matrix: O(V2)O(V^2)
Topological sort O(V+E)O(V + E) DFS by decreasing finish time, or Kahn
SCC (Kosaraju, Tarjan) O(V+E)O(V + E) Kosaraju: DFS on GG, then on GTG^T by decreasing finish
Articulation points, bridges O(V+E)O(V + E) DFS low values
Prim, binary heap O(Elog⁡V)O(E\log V) Fibonacci heap O(E+Vlog⁡V)O(E + V\log V); matrix O(V2)O(V^2)
Kruskal O(Elog⁡E)O(E\log E) sorting dominates; union-find O(α(V))O(\alpha(V)) per op
Dijkstra, binary heap O((V+E)log⁡V)O((V + E)\log V) no negative edges
Bellman-Ford O(VE)O(VE) detects negative cycles
DAG shortest paths O(V+E)O(V + E) relax in topological order, any weights
Floyd-Warshall O(V3)O(V^3) all pairs, negative edges allowed

DFS edge classes (directed, by colour of vv when edge (u,v)(u, v) is seen):

vv is Edge Note
white tree
gray (on stack) back cycle exists
black, d[u]<d[v]d[u] < d[v] forward
black, d[u]>d[v]d[u] > d[v] cross
  • Undirected DFS: only tree and back edges. Undirected BFS: tree and cross edges; levels differ by at most 1.
  • Component graph of SCCs is always a DAG.
  • Articulation point: DFS root with ≥2\ge 2 children; non-root uu with a child vv having low[v]≥d[u]low[v] \ge d[u]. Bridge (u,v)(u, v): low[v]>d[u]low[v] > d[u].
  • Topological order count: adding an isolated vertex to a DAG on nn vertices multiplies the count by n+1n + 1.

MST facts:

  • Cut property: the lightest edge crossing any cut is in some MST.
  • Cycle property: the unique heaviest edge on a cycle is in no MST.
  • Distinct weights imply a unique MST. MST has V−1V - 1 edges.
  • MST minimises the maximum edge on paths (bottleneck), but the MST path is not a shortest path.

Shortest path facts:

  • Bellman-Ford: after round ii, all shortest paths with at most ii edges are correct. One extra round that still relaxes an edge means a negative cycle reachable from ss.
  • Dijkstra can be wrong with a negative edge even without a negative cycle.
  • Adding a constant to every edge can change shortest paths; multiplying by a positive constant cannot.
  • Floyd-Warshall: D(k)D^{(k)} allows intermediates {1,…,k}\{1, \dots, k\} only; a negative D[i][i]D[i][i] means a negative cycle.