FIT2004 Unit Cheatsheet
Context: FIT2004_MOC · whole unit W1–W12, syllabus-ordered · the rigour layer (recurrences, bounds, invariants); links for depth only.
Read order: untagged = PT-critical, must be automatic · [C] = Credit interview · ⛔ = precondition / trap where marks die · each section ends in a folded 🎓 Depth block (D/HD rigour + applied-sheet extensions) — open it only once the visible lines are fluent.
Quick Revision
- 🎯 Objective: write the recurrence → telescope to a level-sum → read the regime off the ratio → quote the tightest with its case and its space.
- ⚡ Key Constraint: a growth class without the derivation line earns nothing — the marks are in the general form in and the base case that fixes it.
1️⃣ Analysis Discipline (W1)
Bound ≠ case sank Q1 of the 2026 S1 D/HD paper — every complexity claim names BOTH.
Case [C] | Analyses | W1 witness |
|---|---|---|
| Best | cheapest input of size | naive D&C multiply ➔ best worst, no branching |
| Worst | dearest input of size | quicksort, extreme pivot ➔ |
| Average | expectation over an input distribution | quicksort, random pivot ➔ |
| Amortised | worst-case total over a sequence length | a guarantee, not a probability |
- Two independent axes
[C]➔ the case picks which function; the bound fences it · ⛔ every pairing is legal — ” means best case” is the examined misconception. - Bound axis ➔ upper · lower · tight · pass-tier: answer as , but a D/HD question makes you justify the side.
- Definitions
[C]➔ : , · : · : · ⛔ no witnesses ⟹ no marks. - Valid ≠ tight ➔ is () and , not since · ⛔ “not the tightest” never makes an claim false.
- Unqualified “complexity” = worst case ➔ best worst only with an early exit or item values steering control flow; otherwise state one for all cases (selection, Merge Sort).
- Input size
[C]➔ element count for a collection, bit-length for a number ⟹ iterations on input is . - Capped parameter =
[C]➔ · ⛔ list which parameters may grow before quoting. - Space = auxiliary ➔ total input auxiliary; quote auxiliary, in-place auxiliary · ⛔ the recursion stack counts, .
- Time auxiliary space ➔ self-check: time with auxiliary is impossible.
- Output size
[C]➔ reporting costs ; grows with the instance so it can’t be dropped ➔ Output-Sensitive Complexity. - Big-O algebra ➔ · · ⛔ upper bounds only.
- Ladder ➔ .
🎓 Depth
- Declare unit-cost
[D]➔ ” is ” needs machine-word operands; iterative Fibonacci is word-ops but bit-ops.- Per-op worst × count is an UPPER bound only
[D]➔ tightness needs a witness where the worst cases co-occur ( sorted Binary Search Tree (BST) inserts ⟹ ).- for problems / for algorithms is a convention
[D]➔ algorithm’s meets problem’s ⟹ provably optimal; “any BST insert is ” is still well-formed and true.
2️⃣ Identities That Do the Work (W1)
Assume no formula sheet — memorise every closed form; prove both series by induction.
- Log algebra ➔ · · · · · · base change is a constant ⟹ needs no base.
- Arithmetic ➔ — shrink-by-one recurrences, quadratic sorts, sorted BST builds.
- Geometric ➔ · ⛔ (at : ).
- ➔ — complete binary tree; the leaf level outweighs all levels above.
- ➔ — halving work totals the top level, independent of .
- Induction blueprint
[C]➔ base → assume → add the -th term to the assumed closed form, refactor · ⛔ cite the hypothesis explicitly. - Induct over the domain
[C]➔ exists only at : step , never ; closing move .
🎓 Depth
- Exponent swap
[D]➔ , since — turns a leaf count into a power of .- Fibonacci doubling
[D]➔ · , from via · ⛔ indexing; eliminate · index halves ⟹ ➔ Fibonacci Sequence.
3️⃣ Recurrence Solving — Telescoping (W1)
Exam format — write every step (marks are for the steps; exemplar in Solving Recurrences (Telescoping))
0 levels · 1 substitute, keep visible · 2 general · 3 base · 4 closed form · 5 · 6a check · 6b substitute back into the RHS (needs ).
- Write it piecewise ➔ for · for · ⛔ is the source’s guard (
if n < 3⟹ ), not a reflexive . - counts call sites, not coefficients ➔
2 * f(n//3) + 4⟹ ·f(n//3) + f(n//3) + 4⟹ . - Threshold base
[C]➔if n < 3with : — solve with the real threshold, drop constants at the end. - Scope ➔ only shrinking arguments are assessed · telescoping is required (closed form ⟹ , handles ) · Master Theorem is supplementary, gives only, fails on .
| Recurrence | Depth | Accumulates | Closed form |
|---|---|---|---|
| constants | |||
| arithmetic | |||
| geometric ratio | |||
| constants | |||
| geometric | |||
| geometric | regime below | ||
| branching tree, nodes |
- Level-sum
[C]➔ — level holds subproblems of size · ⛔ equal-sized subproblems, combine. - Regime from
[C]➔ root-dominated · · leaf-dominated . - Instances ➔ · · · · ⛔ = recursive calls, never the combine’s shifts/adds.
- Subtract ⟹ depth · divide ⟹ ➔ depth and per-level work are independent choices.
- Branching by subtraction = exponential ➔ vs · ⛔ has two arguments ⟹ bound by the tree.
- “Prove by induction” ≠ Step 6b
[C]➔ closed form is given, nothing telescoped: base cited hypothesis step, over the domain ➔ §2️⃣.
🎓 Depth
- Leaf identity
[D]➔ — the collapse behind every D&C exponent.- 🔭 Master Theorem (supplementary) ➔ : · · · ⛔ multiplicative shrink only — on it gives a wrong answer.
4️⃣ Recursive Time and Space in One Pass (W2)
Protocol: read + argument shrink + per-call work → recurrence → telescope for time; same depth → auxiliary space ➔ Analysing Recursive Algorithms (Time and Auxiliary Space).
- Auxiliary ➔ never · ⛔ siblings run sequentially — one root-to-leaf chain is live.
- Single-call recursion ⟹ time class space class ➔ only branching () decouples them.
- Fibonacci decouples
[C]➔ time counts nodes, auxiliary counts height · ⛔ say which you measure. - Shrinking allocations sum
[C]➔ Merge Sort scratch ⟹ , not . - Iterative rewrite drops the stack ➔ same time, auxiliary — why Binary Search and Linear Search are loops.
5️⃣ Divide & Conquer (W1–W2)
- Shape ➔ divide → conquer → combine · ⛔ subproblems independent; overlapping ones need DP.
- Balance sets depth
[C]➔ even halves levels · lopsided levels ⟹ · one half work ⟹ . - Split/combine trade
[C]➔ Merge Sort trivial split, heavy combine · Quick Sort the reverse · Binary Search one subproblem. - Unseen problem — ask in order ➔ (1) answer within-left within-right cross? (2) cross in ? (3) does per-call work shrink? · ⛔ (3) fails silently.
- Strengthen the contract
[C]➔ return more than the answer — Counting Inversions also returns the subarray sorted. - Count the cross term in blocks ➔ emitting with unconsumed adds · ⛔ counts merge steps, not inversions.
- Per-call work must shrink ➔ 2D Local Maximum (Peak Finding): column split keeps a scan ⟹ ; cutting both axes ⟹ .
- Discarding needs an existence claim
[C]➔ “a peak lies in the kept quadrant — an increasing walk can’t re-cross the cross” is the marked sentence.
🎓 Depth
- The is bought by the combine
[D]➔ but .
6️⃣ W1–W2 Algorithm Bounds
| Algorithm | Recurrence | Time (B/A/W) | Auxiliary | Discriminator |
|---|---|---|---|---|
| Schoolbook multiply | — | all | every digit pair | |
| Naive D&C multiply | all | ⟹ no gain | ||
| Merge Sort | all | stable via <= from the left half | ||
| Quick Sort | avg | / W | pivot quality | |
find_min | — | all | no early exit ⟹ B W | |
build_list(n) | — | all | input is a number | |
| Linear Search (recursive) | / / | early return | ||
| Binary Search | / / | iter · rec | early return | |
f(n)=2*f(n//3)+4 | one call site | |||
f(n//3)+f(n//3)+4 | two call sites | |||
power | decrement | |||
power_better | passes x*x — halving alone is wrong | |||
POW(x,p/2)*POW(x,p/2) | call written twice fills the tree | |||
y=POW(x,p/2); y*y | bind once ⟹ : | |||
naive fibonacci | nodes vs height | |||
| Counting Inversions | also returns sorted | |||
| Peak, gradient walk | — | / — / | ridge adversary | |
| Peak, column split | , fixed | scan never shrinks | ||
| Peak, window frame | ||||
| Range report, scan | — | touches all | ||
| Range report, search scan | — | optimal: meets |
- Asymptotic win ≠ faster in practice
[C]➔ a lower exponent bought with extra additions carries a big constant — never a claim about a particular .
7️⃣ Proof of Correctness (W3)
Correctness invariant termination. Invariant alone is partial correctness; termination alone may stop with the wrong answer.
- Answer template ➔ (1) invariant quantified over the counter (2) measure that strictly decreases (3) invariant postcondition · ⛔ the invariant names the data — “
iincreases” is not one ➔ Invariant. - Three-part induction ➔ initialisation · maintenance · termination.
- Termination ➔ finite domain · known start · monotone progress to the bound · recursive: name the shrinking argument and its base case.
- Variant
[C]➔ , · ⛔ strictly — “may stay equal” is where infinite loops live. - Design order
[C]➔ invariant first, then code; weakest statement that implies the postcondition. - Exam shape ➔ “(1 mark) write a loop invariant for Floyd–Warshall…” — prose algorithm in, one quantified sentence out.
| Algorithm | Loop invariant | Termination |
|---|---|---|
find_min | my_min array[0…index] | index from , increments, finite array |
| Selection sort | my_list[0…i-1] sorted AND all of my_list[i…N] | , only increment |
| Insertion sort | my_list[0…i-1] sorted (not final) | increments; decreases to |
| Binary Search | key in array[0…N] key in array[lo…hi] | must strictly shrink |
- The
lo = midhang ➔ at , ⟹ no-op, never terminates · fix:mid + 1, orwhile lo < hi - 1with exclusivehi = len(array).
8️⃣ Sorting — the Four-Axis Suite (W3)
Rank every sort on correctness · time B/A/W · auxiliary space · stability. Most-dropped factors: the comparison cost and the recursion stack.
| Algorithm | Best | Average | Worst | Auxiliary | Stable | In-place |
|---|---|---|---|---|---|---|
| Selection | No | Yes | ||||
| Insertion | Yes | Yes | ||||
| Heapsort | No | Yes | ||||
| Merge Sort | Yes | No | ||||
| Quick Sort | Depends | No | ||||
| Counting Sort | · stable | engineered | No | |||
| Radix Sort | required | No |
- binds comparison sorts only ➔ merge/heap are optimal there; counting/radix escape it by assuming bounded integer keys.
- Comparison cost multiplies everything ➔ per string/tuple compare ⟹ , · integers are by hardware
[C]— the item type decides whether drops. - Recursion stack is auxiliary ➔ recursive sorts are never in-place ⟹ the only in-place sort is Heapsort.
- Shift = stable, long-distance swap = unstable
[C]➔ insertion/merge/bubble shift · selection/heap/quick jump equal keys ([4a,2,3,4b,1]→[1,2,3,4b,4a]) · selection has no best case. - Forcing stability costs space, never time ➔ parallel index list compared on ties ⟹ auxiliary .
- Comparisons swaps
[C]➔ self-check on any derived count. - Counting Sort phases ➔ max → allocate → tally → rebuild · ⛔ quote only if is capped (alphabet , digits ).
- Which variant? ➔ unstated ⟹ bucket · “count array and position array” ⟹ prefix-sum variant (PT-01 signature).
- Stable (prefix-sum) variant ➔
position[first] = 1, ; scan input forwards, writeoutput[position[key]], increment. - Bucket space , not ➔ buckets partition the input, — lecturer’s “very common misconception”.
- Bucket drain
[C]➔extend(), neverpop(0)( shift ⟹ ). - Negative keys
[C]➔ store at , range , add back. - Radix Sort stable counting sorts, LSD first ➔ ⛔ every pass stable, or lower digits’ order is destroyed.
- clash
[C]➔ counting sort: max key · radix sort: base — say which. - Digit of ➔ · columns — radix’s only use of
max(counting uses it to size the array) · lecturer’s recurring code-review error. - Base buys linearity ➔ keeps a pass ; ⟹ ⟹ · ⛔ lets the count array dominate ·
[C]raising shrinks but grows . - Ragged keys
[C]➔ pad with a filler below every symbol · right-aligned numeric order, left-aligned lexicographic.
🎓 Depth
- Auxiliary carries no
[D]➔ count/position/output arrays are reused each pass; only the input is .- “Radix is ” needs a hypothesis
[D]➔ capped key width; distinct base- keys force ⟹ .- Ragged-string radix in
[D]➔ counting-sort by length ascending , sweep sorting only the window of strings with length · ⛔ ascending, socatprecedescats; naive padding is .- Constant-factor base
[D]➔ minimise ; ⟹ , passes · pick , ⟹ shift-and-mask.- Comparison model proves , never
[D]➔ binary-insertion sort makes comparisons yet runs — it still shifts.- “In-place” depends on the cost model
[D]➔ machine words; strict RAM pointers need bits ⟹ relaxed to , excluding pointers, or — say which.
9️⃣ Quicksort, Selection and the Applied Suite (W3 applied · W4 · PT-01)
Every W4 bound is a pair — expected and worst differ. Quoting one without naming it is unmarkable ➔ §1️⃣.
| Partition scheme | Writes | Extra space | Returns | Stable | Pick it when |
|---|---|---|---|---|---|
| Out-of-place | copies | stack | pivot’s final index | No · Yes with a 3rd buffer | stability contractual, memory free |
| Hoare’s | swap per item | pivot’s final index (this unit) | No | large records ⟹ writes dominate | |
| Lomuto’s | 1 swap per item | pivot’s final index | No | correctness under exam time | |
| Dutch flag (3-way) | 1 swap per misplaced item | two boundaries | No | many duplicates, |
- Return contracts ➔ Lomuto and this unit’s Hoare return the pivot’s final index ⟹ recurse
(start, j-1),(j+1, end)· textbook Hoare returns a split point ⟹(start, j),(j+1, end)· ⛔ name the contract first ➔ Partitioning (Quicksort). - Hoare invariants ➔ left of
L_bad· right ofR_bad· between is unprocessed, empty when pointers cross · ⛔ guard the final pivot swap. - Dutch flag invariants ➔
[1 … boundary1-1]·[boundary1 … j-1]·[boundary2+1 … N]·[j … boundary2]unprocessed, exitj > boundary2· ⛔ the branch must not advancej. - 3-way for duplicates
[C]➔ recurse on the outer two ⟹ depth , all-equal input · a 2-way split never retires equal keys. - Schemes differ in writes, not comparisons
[C]➔ Hoare fewer writes than Lomuto — matters for large records. - Stability
[C]➔ Hoare’s final pivot swap jumps the pivot ⟹ unstable regardless · out-of-place≤ pivotis still unstable ⟹ add an== pivotbuffer. - Average height (“green area”) ➔ middle-half pivot w.p. leaves ⟹ , average depth , per level.
- Pivot judged on fraction, not balance ➔ fixed split is still depth · needs a constant-size split every level (minimum pivot ⟹ every input).
- Random vs guarantee ➔ random pivot makes the bad input unconstructible (expected , worst ) · Median of Medians makes it impossible (worst ) — the W4 hinge.
- Quicksort is never in-place ➔ live frames are auxiliary: worst, by recursing the smaller side first and looping on the larger.
- Order statistics
[C]➔ at · median · — one algorithm. - Sort-then-slice is the baseline ➔ , = comparison cost · counting/radix can’t be assumed.
- Quickselect ➔ partition at : return · left · right, unchanged (absolute indices) ⟹ expected, worst.
- Quickselect best is ➔ one full partition is unavoidable · tail call ⟹ auxiliary as a loop
[C]. - Median of Medians ➔ , ⟹ · ⛔ groups of sum to ⟹ · examinable since 2023 — a hand skill.
- MoM by hand ➔ groups of → insertion-sort each → read medians → quickselect their median → partition on it · base .
- The ➔ on each side ⟹ worst split .
- Co-recursion
[C]➔ MoM ↔ quickselect; both arguments shrink (, ), is the shared base. - K-way Merge ➔ scanning heads → min-Heap of heads , auxiliary · entries
(value, list id, index)[C]· ⛔ heap stays size — seeding all is heapsort. - Online vs offline decides admissibility first ➔ online valid answer at every arrival · quickselect is yet unusable on a stream · insertion sort / heap
addonline; merge sort /build_heapnot ➔ Online Algorithm. - smallest ⟹ size- MAX-heap ➔ root eviction threshold; arrival root rejected in ⟹ , · largest ⟹ min-heap.
- Sort as preprocessing
[C]➔ buys adjacency and binary search · dedup with read/write pointers (shift-delete ). - An “in-place” spec picks the sort ➔ Heapsort is the only valid choice — naming it is the marked step.
- Optimality by reduction
[C]➔ singleton lists -way merge a comparison sort ⟹ for merging.
| W4 algorithm | Time (B/A/W) | Auxiliary | Online? | Discriminator |
|---|---|---|---|---|
| Quick Sort (random pivot) | / / | smaller-first · naive | No | smallest constant of the sorts |
| Quick Sort Median of Medians | all | No | worst case eliminated, big constant | |
| Quickselect (random pivot) | / / | iterative | No | one rank |
| Quick Sort exact-median Quickselect | / / | No | no gain — inherits quickselect’s worst | |
| Quickselect Median of Medians | all | No | linear worst-case selection | |
| K-way Merge (min-heap) | all | Yes | external sorting | |
| K-way Merge (scan heads) | all | Yes | only for | |
| Size- heap | all | Yes | unbounded or memory cap |
🎓 Depth
- Average case from the recurrence (NOT examinable) ➔ after subtracting the instance ⟹ via the harmonic tail .
- Exact-median pivot doesn’t fix quicksort
[D]➔ quickselecting it is worst ⟹ ; a pivot in linear worst time is what closes it.- The mean is not the median
[D]➔ on the element nearest the mean is the second-largest ⟹ · no guaranteed proportional cut ⟹ no log depth.- Naive 3-way groups duplicates, Hoare scatters them
[C]➔[7,1,12,9,3,3,10,6,7,14,4], pivot : naive[1,3,3,6,4,7,7,12,9,10,14]· Hoare[6,1,4,7,3,3,7,10,9,14,12].- -partitioning
[C]➔ sequential · middle pivot then recurse both halves · is sorting ⟹ .- Quickselect expected by coins
[C]➔ good pivot (middle ) leaves , ⟹ tries ⟹ .- Weighted median
[C]➔ compare weight sums, not ranks; recurse into the heavier side with reduced · ⛔ permute weights in unison.- closest to the median in
[C]➔ quickselect , then the -th smallest , take strictly smaller and top up from ties · reada[i]as in place ⟹ extra.- Hybrid merge + insertion
[C]➔ · ⛔ constant, or dominates.- Locks and keys
[D]➔ pivot keys on a lock, locks on the matching key ⟹ average.- Order statistic of two sorted arrays
[D]➔ is monotone ⟹ nested search · simultaneous searches .
🔟 Graphs, Traversal and Shortest Paths (W5)
Every graph bound has two parameters and a representation: is adjacency-list ( sparse, dense); the same code on a matrix is .
- Definitions ➔ · directed from to · weighted · simple no self-loops or multi-edges (assumed unless told).
- Max edges ➔ directed , undirected , both · sparse , dense — picks the representation and turns into .
| Space | Edge exists? | Neighbours of | Traversal | |
|---|---|---|---|---|
| Adjacency matrix | always | row scan | ||
| Adjacency list | , early exit if sorted |
- Sorted linked list ≠
[C]➔ only early exit; binary search needs a sorted array. - Traversal ➔ each vertex served once each undirected edge seen twice · ⛔ “discovered?” is an flag, not a queue search ().
- Three states ➔ undiscovered → discovered (in the collection) → visited (served) · hand trace: a
Discoveredrow and aVisitedrow every step. - The frontier ADT is the algorithm ➔ queue BFS · stack DFS · min-Heap Dijkstra — every other line identical.
- Tie-breaks apply at insertion ➔ alphabetical: BFS appends A→Z, DFS pushes Z→A · ⛔ same-layer vertices leave in queue order · order depends on adjacency order — state it
[C]. - BFS = unweighted shortest distance ➔ at discovery
v.distance = u.distance + 1,v.previous = u· ⛔ FIFO and uniform cost · DFS depths are not distances[C]. - Traversal uses
[C]➔ reachability · components · cycle detection · unweighted shortest path · Topological Sort. - Dijkstra DP greedy ➔ closest unfinalised vertex is finalised on serve · ⛔ — a negative edge cheapens a detour after finalisation.
- Relaxation ➔ not finalised: undiscovered ⟹ set ; else update only if ; rewrite
v.previouson every success. - Dijkstra bounds ➔ binary heap (dense: the slide’s ) · Fibonacci heap · ⛔
updateneeds a vertex → heap-slot index map, else each. - Update vs duplicate heap ➔ duplicates (
heapq): one push per relaxation, heap , stale entries skipped on serve · ⟹ same bound. - Matrix Dijkstra
[C]➔ — reads are , heap ops only per edge · ⛔ not . - Single target
[C]➔ stop when the target is visited; backtrackprevious, reverse. - DAG ➔ no directed cycle (undirected cycles fine) · = before .
- Topological Sort ➔ before for every edge · not unique · exists DAG.
- Kahn’s ➔ count in-degrees → seed zeros → pop, emit, decrement out-neighbours, push new zeros ⟹ · ⟹ cycle · queue or stack both valid.
- Modified DFS ➔ push on finish, then reverse ⟹ · ⛔ DFS pre-order is not topological (top error) · seed every vertex.
- Which one
[C]➔ Kahn’s: free cycle check, layered batches, no recursion · DFS when a traversal already exists ·processnever ⟹ the order is unique.
🎓 Depth
- Parametrised re-derivation
[D]➔ append , serve , update : — on a swapped heap re-derive, never re-quote ➔ Dijkstra’s Algorithm.- Dijkstra correctness
[D]➔ suppose shorter ; last vertex of in , its successor; ⟹ served first, or · ⛔ that first is where is spent.
🔟.b The W5 Applied Sheet — Traversal, Recast
| W5-applied task | Time | Auxiliary | Discriminator |
|---|---|---|---|
| Two-colour / bipartiteness | first colour free, rest forced | ||
| Count two-colourings | , or | ||
| Directed cycle | edge into an active vertex | ||
| Undirected cycle | halts early; independent of | ||
| Shortest cycle (directed) | one BFS per source | ||
| Count pure-cycle components | conjunction of | ||
| Multi-source BFS / super source | subtract for the extra hop | ||
| State-graph BFS | one slot per state | ||
| Universal sink (matrix) | one candidate killed per cell | ||
| Bridges | beats delete-and-recount | ||
| Guaranteed top- in a DAG | two DFS per vertex | ||
| Hamiltonian path in a DAG | unique topological order |
- Two-colouring is greedy, not search ➔ first vertex of a component is free, the rest forced · ⛔ fail only on a neighbour with the same colour · bipartite two-colourable.
- Directed cycles need three states ➔ unvisited / active / inactive; fire only on an edge into an active vertex ➔ Cycle Detection · ⛔ the undirected rule false-positives on the diamond , .
- Multi-source shortest path ➔ seed the queue with all sources at , or a super source and subtract · transform the input, keep the algorithm a black box.
- State-graph BFS
[C]➔ when the optimum revisits a vertex, use , wire only legal transitions, answer over accepting states · constant is free; an input capacity must appear in the bound ➔ State-Space Graph Modelling.
🎓 Depth
- Counting two-colourings
[C]➔ if any component fails, else · ⛔ isolated vertices are components.- Undirected cycle is
[D]➔ acyclic ⟹ ; cyclic ⟹ halts at the first non-tree edge · bound by work before the halt.- Shortest cycle
[C]➔ BFS from every vertex, testif v == s· one BFS orders by distance from its source, missing a short far cycle.- Pure-cycle components
[C]➔ every · ⛔ never early-return, or the remainder is recounted as a new component.- Iterative DFS
[C]➔ explicit stack, testvisitedon pop — filtering at push breaks · neighbours come off reversed.- Universal sink
[D]➔ kills , () kills ; linked list of live candidates ⟹ reads verify ➔ Graph Representations §3.- Bridges by low-link
[D]➔ bridge on no cycle for tree edge · · ⛔ mixed and strict comparison; mark the tree edge before recursing ➔ Bridges (Low-Link).- Guaranteed position in every topological order
[D]➔ reachable, reaching · always in first · never .- Hamiltonian path in a DAG
[D]➔ exists topological order unique consecutive pairs adjacent ⟹ — acyclicity leaves one candidate ➔ Topological Sort §5.
1️⃣1️⃣ Minimum Spanning Trees, Union-Find and Greedy (W6)
Most-examined W6 sentence: "can Prim/Kruskal run on negative weights?" — YES. Non-negativity is Dijkstra's precondition; importing it here loses the mark.
- MST ➔ acyclic undirected spanning subgraph minimising ; every spanning tree has edges · ⛔ connected and undirected, else spanning forest · = min to connect = max without a cycle
[C]➔ Spanning Tree. - Cost unique, tree not ➔ write an MST, state the tie-break, quote the selection order.
- Negatives are legal ➔ both only compare weights · adding to every edge adds to every tree ⟹ same MST.
- Maximum spanning tree
[C]➔ max-heap Prim · descending Kruskal · or negate every weight. - Prim Dijkstra with one line changed ➔
v.distance = w(distance to the tree) ⟹ finalisation order not nondecreasing · no cycle test needed[C]. - Prim bounds ➔ with heap index map · array scan on dense graphs.
- Kruskal ➔ sort ascending → accept iff
find(u) != find(v)→union→ stop at edges · ⛔ comparison sort unless integer weights are stated. - Kruskal ladder ➔ set copy · smaller-into-larger · union-find since — sort dominates.
- Prim vs Kruskal
[C]➔ dense / matrix ⟹ Prim · sparse / edge list / presorted ⟹ Kruskal. - Union-find encoding ➔ one
parentarray: positive parent, negative root with size/rank magnitude, init · ⛔ magnitude meaningful only at a root —findfirst. - Union by size ➔ smaller under larger; tie ⟹ first argument’s root wins · ⟹ height ⟹ per op.
- path compression
[C]➔ re-point the walked path at the root ⟹ ~ amortised · fires on refused unions too · stored rank becomes an upper bound. - Greedy ➔ ranking rule feasibility irrevocable commit · needs greedy-choice and optimal substructure (DP: substructure only).
- Interval scheduling ➔ max count: earliest finish first ⟹ · proof: by induction.
- Rules that fail
[C]➔ shortest duration: · earliest start: first request finishes last · kill rivals by counterexample first. - Weighted intervals ⟹ DP
[C]➔ substructure survives, greedy choice doesn’t. - - BFS
[C]➔ deque: -edges to front, -edges to back,d == dist[u]staleness guard ⟹ . - State-graph Dijkstra
[C]➔ cost depends on more than location ⟹ state in the vertex, e.g. with refuel edges weight ➔ State-Space Graph Modelling. - Buggy-Dijkstra witness ➔ to break “update only on first discovery”: locks at , not .
| W6 algorithm | Time | Auxiliary | Weights | Discriminator |
|---|---|---|---|---|
| Prim’s Algorithm (heap) | any sign | one tree, no cycle test | ||
| Prim’s Algorithm (array) | any sign | dense graphs | ||
| Kruskal’s Greedy Algorithm union-find | any sign | presorted ⟹ | ||
| Kruskal’s Greedy Algorithm naive sets | any sign | the is in union | ||
| Union-Find (Disjoint Set) by size/rank | /op | — | for all unions | |
| path compression | ~ amortised | — | flattens on refused unions | |
| Interval scheduling | beyond sort | — | count, not value | |
| - BFS (deque) | two-key priority queue | |||
| Dijkstra bucket queue | integer | minimum never decreases |
🎓 Depth
- MST cut-and-swap
[D]➔ invariant: chosen set some MST ; if omits , has a cycle re-crossing the cut at with ⟹ is an MST containing · never uses .- Reverse-delete
[D]➔ sort descending, delete iff stays connected; invariant some MST ➔ Minimum Spanning Tree §5.- A true invariant can be too weak
[D]➔ “each Kruskal component is an MST of its vertices” can’t close the proof — counterexample ➔ Invariant.- Bottleneck paths
[D]➔ every MST path minimises its largest edge (swap its heaviest edge for a lighter crossing edge) · converse false.- Union-by-size lemma
[D]➔ base ; keeps height; gives .- Amortised ≠ per-op
[D]➔ one compressedfindcan still cost .- Greedy proof templates
[D]➔ exchange (edit an optimum to contain your choice — MST) · stays ahead (your -th choice no worse — scheduling) · both still owe termination.- Bucket-queue Dijkstra
[D]➔ : linked-list buckets, insert/update, one forward sweep .
1️⃣2️⃣ Dynamic Programming (W7 · PT-02)
PT-02's recurrence describes the value stored in the MEMO — not PT-01's time-complexity recurrence. Same word, different object.
- Two ingredients ➔ overlapping subproblems (reuse pays) optimal substructure (sub-optima compose).
- DP vs D&C ➔ same skeleton; DP’s sub-solutions are optimal and reused because they overlap · no repeats ⟹ a memo buys nothing.
- DP vs greedy ➔ greedy also needs the greedy-choice property and commits; DP defers · no safe ranking rule ⟹ DP.
- Brute force with a table
[C]➔ still enumerates every choice; saves recomputation, paid in auxiliary space · Fibonacci . - MEMO as an English sentence ➔
DP[i] = {max profit from a subset of houses [1..i]}— the recurrence is read off it · ⛔ no sentence, no DP. - Three case groups ➔ base (written in; needed for backtracking) · general (the / decision) · edge (boundary, no decision) · if two can fire, “first match wins”.
- Auxiliary number of subproblems ➔ one per MEMO dimension · ⛔ the choice set is not a dimension (coin change: space, time).
- Time subproblems work each ➔ quote both factors.
- Answer location ➔ fixed cell (coin change, LCS, interval DP) or scan (LIS, max subarray) · anchored “ending at ” always costs a scan.
- Top-down vs bottom-up
[C]➔ same complexity · top-down skips unneeded subproblems · bottom-up fill order is a correctness condition ➔ Interval Dynamic Programming. - Reconstruction ➔ decision array (faster) vs backtracking (less auxiliary, same class) · store the last decision, never the whole combination ().
- Backtracking = inclusion test ➔ compare against the skip branch: knapsack vs row above (differs ⟹ taken, move up and left ) · salesman takes iff · ⛔ strict; a invents a choice.
- Memo sentinel outside the answer range ➔ , never (a legal “unreachable” answer).
- Syllabus ➔
- pass: Fibonacci · coin change · unbounded and knapsack · neighbour houses · LIS · maze
- pass, off-deck: rod cutting (= unbounded knapsack, length as weight) · edit distance (tutorial videos, with LCS)
- credit: LCS · LIS · matrix chain · the applied sheet
- Coin change ➔ if · if every · else · PT-02 sample is this with microwave keys .
- Greedy coin change fails ➔ for : greedy () vs () · canonical currencies prove nothing.
- Coin hand-table ➔ , : · last coin ⟹ · ⛔ not monotone.
- Unbounded knapsack ➔ coin change with and init : · ⛔ the carry fixes “exactly ”.
- knapsack ➔ if , else ; bases · ⛔ read the row above, or the item becomes reusable.
- Why 1-D vs 2-D ➔ unlimited items ⟹ weight alone is a sufficient state · single-use ⟹ row encodes “first items on offer”.
- Knapsack instance
[C]➔ , , , , capacity : unbounded () · () · ⛔ swapping the two answers loses the question. - Two-row trick
[C]➔ value only ⟹ roll two rows · which items ⟹ keep the matrix. - Salesman / neighbour houses ➔ , , · (houses ) · ⛔ the is not taken.
- Grid DP ➔ paths (disjoint sets add) · max money · , answer · top row / right column have one move.
- Four subproblem shapes
[C]➔ prefix/suffix · cut a sequence everywhere, · two prefixes of two sequences · a contiguous range. - Add a dimension
[C]➔ if the optimum revisits a position, position isn’t a sufficient state (two-sided street:DPleft,DPright).
| W7 DP problem | Subproblems | Work each | Time | Aux | Answer |
|---|---|---|---|---|---|
| Coin change | values | ||||
| Unbounded knapsack | weights | ||||
| knapsack | |||||
| Salesman houses | |||||
| Grid paths / max money | |||||
| LIS | scan | ||||
| Box stacking | scan | ||||
| LCS / SCS | |||||
| Interleaving | |||||
| Max subarray (prefix sums) | |||||
| Max subarray (anchored) | scan | ||||
| Max-sum submatrix | scan | ||||
| Palindromic subsequence | |||||
| Coin game | w/ prefix sums | ||||
| Boolean parenthesisation | |||||
| Ferry (two lanes) | |||||
| Word break | |||||
| Text justification | |||||
| Tree broadcast |
🎓 Depth
- Delete a redundant parameter
[D]➔ derivable index ≠ dimension: ferry ⟹ · interleaving ⟹ · ⛔ prefix sums keep it .- Collapse the table
[D]➔ look-back cells: max subarray auxiliary, LCS length · ⛔ no rolling when asked which.- Tree DP
[D]➔ , children sorted descending (slowest subtree first) · counting sort ⟹ .- Non-crossing bridges
[D]➔ state (house, furthest-right bridge): if · keep only the monotone frontier.- Grouping with spread
[D]➔ sort, → monotone pointer partial sums · sorting safe by exchange ➔ Greedy Algorithm §3.- Ordered cases
[D]➔ wildcard matching: first match wins; cache “any true” filling descending ⟹ .- DP over a DAG
[D]➔ reverse topological order: paths ⟹ · for critical path · unbounded knapsack critical path on .
1️⃣3️⃣ Shortest Paths With Negative Weights (W8)
The sign of the weights picks the algorithm; the number of sources picks it again. Dijkstra with one negative edge is wrong, not suboptimal.
- Bellman-Ford is DP, not greedy ➔ nothing finalised · relaxation identical to Dijkstra’s, every edge every round.
- rounds ➔ a shortest path is simple, edges · invariant: after round , every -edge distance is correct.
- -th pass negative-cycle test ➔ any improvement ⟹ negative cycle ⟹ no shortest distances — raise an error.
- Bounds ➔ time, auxiliary (
dist,predonly; the trace grid is a revision device) · dense . - Early exit (required) ➔
changedflag; a quiet round is a fixed point ⟹ break · best . - Detection scope
[C]➔ reachable cycles only · weight- super source ⟹ one run · or the Floyd-Warshall diagonal. - Extract the cycle
[C]➔ walkpredto the first repeat · ⛔ updated vertices may be downstream, not on the cycle. - Guard
[C]➔ testdist[u] != INFbefore relaxing. - Constant shift doesn’t legalise Dijkstra
[C]➔ adds to a -edge path, favouring few-edge paths. - Warshall’s closure ➔
m[i][j] = m[i][j] or (m[i][k] and m[k][j])⟹ , · directed: . - Floyd-Warshall ➔
m[i][j] = min(m[i][j], m[i][k] + m[k][j])· init diagonal , edges, elsewhere. - must be outermost ➔ invariant: after iteration , is shortest using intermediates · · in-place safe (row/col fixed).
- FW bounds ➔ time, space, all cases · never appears.
- Negative cycle ➔ finds any cycle in · every pair routed through it is · post-process
[C]: for negative set where . - Arbitrage
[C]➔ profit ⟹ FW, read the diagonal. - Path reconstruction
[C]➔succ[u][v] = vper edge; on updatesucc[i][j] = succ[i][k]; followi = succ[i][j]. - All-pairs selection ➔ Dijkstra · Bellman-Ford · FW · sparse ⟹ Dijkstras (after Johnson’s if some ), dense ⟹ FW.
| Requirement | Algorithm | Time | Aux | Negatives | Detects negative cycle? |
|---|---|---|---|---|---|
| Unweighted, single source | BFS | — | — | ||
| , single source | Dijkstra | ❌ | ❌ | ||
| Some , single source | Bellman-Ford | ✅ | ✅ reachable only | ||
| Any negative cycle in | Bellman-Ford super source | ✅ | ✅ anywhere | ||
| Reachability, all pairs | Warshall’s closure | — | — | ||
| All pairs, dense | Floyd-Warshall | ✅ | ✅ anywhere | ||
| All pairs, sparse, | Dijkstra | ❌ | ❌ | ||
| All pairs, sparse, some | Johnson’s | ✅ | ✅ via its Bellman-Ford |
🎓 Depth
- Johnson’s potentials
[D]➔ Bellman-Ford distances from a weight- super source; by the triangle inequality; path weights telescope ⟹ Dijkstras, undo · .
1️⃣4️⃣ Tries, Suffix Tries and Suffix Trees (W9 · PT-03)
PT-03 is draw count: the root is a node,
$alone is a suffix, every word/suffix ends in$. One omission shifts every count by one.
- Trie node ➔
links = [None]*27,$at ,a..zat ⟹ child ·$makesappa word afterapple; slot sorts it first. - Search ➔ worst, best, = query length — never appears (sorted array / BST: ).
- Properties ➔ words, longest , total chars incl.
$: nodes , · leaves · height (count the$edge). - Sorted output ➔ in-order DFS,
$first, · ⛔prefix + ccopies strings ⟹ . - Iterative vs recursive
[C]➔ same ; auxiliary vs · recurse when information flows up. - Trie vs hash table
[C]➔ exact membership tight memory ⟹ Hash Table · prefix, order or worst-case bound ⟹ trie. - Payloads
[C]➔ distinct strings$nodes · prefix count:+1on every node passed at insert ⟹ query · max of . - Suffix trie ➔ trie of the suffixes of
S$· substring prefix of a suffix ⟹ · occurrences leaves below · longest repeat deepest node with children · build . - Suffix tree ➔ compress one-child chains, label edges
[start, end]⟹ nodes, space · ⛔ index labels, not text · naive build still (Ukkonen is FIT3155) ·(i, l)1-based start length[i-1, i+l-2].
| PT-03 counts ( = distinct non-empty substrings) | Suffix trie | Suffix tree |
|---|---|---|
| Nodes | to | |
| Inner nodes | to | |
| Leaves | ||
| Height | to | |
| edge lengths | ||
| Smallest on | aaaa ( nodes) | all-distinct () |
| Largest on | all-distinct, | aaaa () |
- Distinct substrings
[C]➔ trie: nodes − root −$nodes, · tree: in . - Think in the trie, answer in the tree
[C]➔- longest common substring: tree of
s1#s2$, deepest node with leaves from both - fewest substrings forming : greedy longest match, restart at root,
- shortest unique: shallowest node with a non-
$leaf edge, depth - shortest absent: shallowest point missing a character
- longest common substring: tree of
- Suffix array / prefix doubling ➔ not examinable 2026 S2 (🔭 block in Suffix Trie and Suffix Tree).
| Query | Structure | Time | Space |
|---|---|---|---|
| Word membership / insert | Trie | ||
| Words with prefix | Trie counter | ||
| Predecessor of a query | Trie | ||
| Substring test / occurrences | tree | leaves below | trie · tree |
| Distinct substrings | suffix tree | after build | |
| Longest repeated / common substring | suffix tree | / after build | |
| Naive build, either suffix structure | — | — |
🎓 Depth
- Predecessor
[C]➔ walk the query remembering the deepest node with a child smaller than the next character; on failure go there, take its greatest smaller child, then greatest children to a leaf ⟹ .- Binary trie
[D]➔ max : prefer the opposite bit, · max subarray XOR , query-then-insert ⟹ .- Trie inside a DP
[D]➔ word break’s prefix test becomes one trie walk ⟹ ➔ §1️⃣2️⃣.
1️⃣5️⃣ Self-Balancing Search Trees (W10 · PT-03)
PT-03 may hand you a half-built tree and mix inserts with deletes. Fix the lowest violation first, then keep checking to the root — deletes cascade.
- Why balance ➔ BST ops cost ; sorted input ⟹ · an invariant forces height .
- AVL invariant ➔ at every node · hand convention: empty , leaf , annotate
h,bf. - AVL insert/delete ➔ BST op at a leaf (internal delete: swap with predecessor or successor, as asked) → update heights upward → restructure the lowest → continue up.
- Trinode restructure ➔ from step twice toward the taller child (tie on step 2 ⟹ repeat step 1’s direction ⟹ single rotation) → median key becomes root → re-hang in order · covers LL, RR, LR, RL.
- AVL bounds ➔ search/insert/delete · heights stored, only the path updated · rotations per fix, at most one per level.
- 2-3 tree ➔ 2-node: key, children · 3-node: keys, children · all leaves on one level · ⟹ .
- 2-3 insert ➔ descend (key met anywhere ⟹ do nothing) → insert at the leaf → a 4-node splits, median up → repeat · root split is the only way height grows.
- 2-3 delete (top-down) ➔ never enter a 2-node; internal key ⟹ swap with pred/succ first
- 2-node root over two 2-nodes ⟹ merge into a 4-node
- 3-node sibling ⟹ rotate (sibling key up, parent key down)
- 2-node sibling ⟹ merge child parent key sibling
- remove at the leaf, then split leftover 4-nodes on the way up
- LLRB encoding ➔ colour lives on the child edge · 2-node black · 3-node black with red left · no red–red · root black · black-height 2-3 height.
- LLRB insert ➔ new red leaf → right red, left not red ⟹ rotate left · both children red ⟹ flip · two left reds in a row ⟹ rotate right, then flip · red right of a red left ⟹ rotate left first → propagate → root black · no delete in FIT2004.
- 2-3 ⟷ LLRB
[C]➔ flip split · root recoloured black root split · rotate left redraw a 3-node leaning left — check one answer with the other.
| Tree | Balance rule | Insert fix | Delete fix | Time |
|---|---|---|---|---|
| AVL Tree | per node | trinode restructure | swap to leaf restructure, cascades | |
| 2-3 Tree | all leaves level | split promote | top-down rotate / merge | |
| LLRB | equal black edges per path | rotate L / rotate R / flip | not in FIT2004 |
🎓 Depth
- AVL height is
[D]➔ sparsest tree ; ⟹ .- Rotation correctness
[C]➔ read subtree heights off the given s, rebuild, show at the three moved nodes.- BST insert/delete correctness
[C]➔ successor of a two-child has no left child · for exactly one of “successor has no left child” / “predecessor has no right child” ⟹ unique insertion slot.- Minimal-height BST
[C]➔ sort, median as root, recurse ⟹ · is optimal, else sorting beats its lower bound.- LLRB height
[D]➔ no two reds in a row ⟹ drawn height black-height .
1️⃣6️⃣ Network Flow (W11 · PT-03)
Two sign rules: the residual backward edge has capacity ; a cut's capacity counts edges only, while its flow subtracts flow.
- Flow network ➔ directed, , source (no in-edges), target (no out-edges) · · conservation in out at · net out of net into .
- Residual network ➔ edge gives forward and backward ; drop zeros, merge parallels · edges · check .
- Augment ➔ any path in · residual · forward , backward cancels · no path ⟹ maximum · forward and backward edges traversed alike (BFS is best).
- Why backward edges ➔ the lecture network stalls at with forward pushes only; cancelling via backward reaches .
- Reading off ➔ flow backward weight · capacity forward backward (the sanity-check sheet’s “flow forward” is a slip).
- FF bounds
[C]➔ per augment, augments ⟹ pseudo-polynomial · unit capacities · Edmonds–Karp · space · integer capacities ⟹ integer flows. - Answer not unique ➔ max-flow value fixed; the edge assignment and min cut may differ.
- Cut ➔ · capacity · flow .
- Find the min cut ➔ FF to completion → search from in the final residual → reached → sum capacities, confirm · ⛔ searching instead of .
- PT-03 run question ➔ may start mid-stage (expect a backward augment) · self-check: re-run from blank — same max flow, maybe a different cut.
- PT-03 modelling checklist ➔ vertices · directed edges · edge count · capacities · lower bounds · demands — each read off the question.
- Reductions ➔ transform the input, never modify FF · owe construction why max flow answer read-off.
- edge
[C]➔ never crosses in a finite min cut ⟹ "" — prerequisites, pinned cells.
| Question asks | Build | Read off |
|---|---|---|
| how much gets through | the network as given | |
| several sources / sinks | cap out-capacity of · cap in-capacity | , value unchanged |
| node throughput limit | split cap ⟹ | |
| pair two groups | , , all cap · quota: cap | middle edges with flow |
| exact counts per row / category | cap · cap · cap | feasible , |
| edge- / vertex-disjoint paths | unit capacities ( split, cap ) | , |
| cheapest two-way assignment | cap cost on computer-s · cap cost on computer-t · two opposite penalty edges per pair | ⟹ computer-t; cut min cost |
| subset with prerequisites, max profit | cap () · cap () · cap | chosen; profit min cut |
| fencing / segmentation | boundary · ground · hole · paired | min cut min cost |
| fewest paths covering a DAG | per edge, max matching | |
| “at least” on a link, fixed supplies / needs | circulation (§1️⃣7️⃣) | feasible super-edges saturated |
🎓 Depth
- Every cut carries
[D]➔ sum conservation over : only is non-zero, – edges cancel.- Weak duality
[D]➔ ⟹ a flow equal to some cut capacity is maximum.- Max-flow min-cut
[D]➔ at FF’s exit, reachable in : every edge saturated, every edge empty ⟹ — this termination is FF’s correctness proof.- Edmonds–Karp
[D]➔ BFS distances never shrink; each edge is the bottleneck times ⟹ augments (beyond the provided material).- Min-cut split drill
[C]➔ cost , ; penalty gives , flipping at .- Path cover, why
[C]➔ each match picks a successor; unmatched left copies are path ends.
1️⃣7️⃣ Circulation with Demands and Lower Bounds (W12)
is a supplier (edge from ); lower bounds enter as minus incoming, plus outgoing.
- Circulation ➔ · at every · no / · feasibility, not optimisation.
- Feasibility by max flow ➔ cap (), cap (), run FF ⟹ feasible every super-edge saturated · delete to read off · quick reject (necessary, not sufficient).
- Lower bounds ➔ per edge : , , → solve → · check .
- Infeasibility certificate
[C]➔ a cut of capacity · Clayton network: but in-capacity . - Modelling ➔ exact count at a vertex demand · range on a link · per-item ranges with a fixed total ⟹ extra vertex carrying · cap on a group of edges ⟹ selector vertex.
- Lecture applications
[C]➔ survey: , , , closing · airline: route , / / chain , , , .
🎓 Depth
- Why the test is exact
[D]➔ (⟸) saturated supplies exactly · (⟹) feasible circulation full super-edges has value ⟹ maximum by weak duality.- Cost
[D]➔ transform , FF — pseudo-polynomial in demands; space .- Baseball elimination
[D]➔ wins all ⟹ · () cap · cap · ⟹ feasible can finish at least tied.