FIT2004 Unit Cheatsheet
Context: FIT2004_MOC · the WHOLE unit in one re-read, syllabus-ordered. This sheet holds the FIT2004 rigour layer (recurrences, derivations, bounds). Currently covers W1–W3; extend each week.
Tier tags: [P] PT-critical, must be automatic · [C] needed for Credit Discussions · [D] D/HD-exam rigour. Drill [P] to fluency before reading a [D] line.
Quick Revision
- 🎯 Objective: every analysis question reduces to ➔ 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: naming 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.
- Two INDEPENDENT axes — never conflate
[C]➔ the case picks which function you analyse; the bound fences that function · precondition: all pairings are legal — FIT1008 quoted for the best case and was right. ” means best case” is the misconception being examined. - The bound axis
[P]➔ upper · lower · tight, i.e. · pass-tier shortcut: if you are only chasing Competent, answer questions as you would — but this shortcut fails the moment a[D]question asks you to justify the side.
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 [D] | worst-case total over a sequence length | a guarantee, not a probability — no distribution assumed |
- Formal definitions — state the witnesses
[C]➔ : with · : with · : with · precondition: every claim needs the constants and the range of ; a proof without witnesses scores nothing. - Valid ≠ tight
[P]➔ is (TRUE, ) and is , but not — killed because leaves no · precondition: on true/false questions answer from the definition; “not the tightest” never makes an claim false. - Unqualified “complexity” = worst case
[P]➔ best/worst diverge · precondition: the code has a short-circuit (break/early return) or input-dependent branching; otherwise best worst (selection sort, Merge Sort) and you may state one for all cases. - Input size
[C]➔ elements for a collection, but bit-length for a number () · precondition: state which you are counting — a loop running times on numeric input is , not . - A CAPPED parameter is and vanishes
[C]➔ becomes ; bit-count constant · precondition: list which parameters may grow before quoting any bound. - Space = AUXILIARY
[P]➔ space input space auxiliary space; quote the auxiliary half, in-place auxiliary · precondition: include the recursion stack — frames, only ONE root-to-leaf chain live at a time. Input space is not the algorithm’s choice; auxiliary is, and it is the column that discriminates. - Time auxiliary space
[P]➔ allocating and filling a cell costs step · use: a self-check — a -time answer paired with auxiliary is arithmetically impossible, so one of the two is wrong. - Output size is a FREE parameter
[C]➔ a reporting algorithm costs ; range report on a sorted array is scanning vs binary-then-scan · precondition: may grow with the instance, so it cannot be dropped — alone is FALSE ➔ Output-Sensitive Complexity. - Declare unit-cost
[D]➔ ” is ” needs machine-word operands · precondition: values whose bit-length grows with cost per op — iterative Fibonacci is word-ops but bit-ops. - Worst-case-per-op × count is an UPPER bound only
[D]➔ tightness needs a witness input where the worst cases co-occur ( sorted Binary Search Tree (BST) insertions ⟹ ). - for problems / for algorithms is a CONVENTION
[D]➔ an algorithm’s meeting the problem’s ⟹ provably optimal; but is defined on any function, so “any BST insertion is ” is well-formed and true. - Big-O algebra
[P]➔ Sum · Product · precondition: upper bounds only — this algebra cannot produce a lower bound. - Ladder
[P]➔ .
2️⃣ Identities That Do the Work (W1)
Assume nothing is provided. The PT formula sheet is not guaranteed — memorise every closed form below and be able to prove the two series by induction.
- Log algebra
[P]➔ · · · · · inverse pair and · consequence: base change is a constant factor ⟹ never needs a base. - Exponent swap
[D]➔ · proof: — the exponent product is symmetric. Turns a leaf count into a power of . - Arithmetic
[P]➔ ➔ shrink-by-one recurrences, quadratic sorts, sorted BST builds. - Geometric
[P]➔ · precondition: (at , ). - corollary
[P]➔ ➔ complete-binary-tree node count; the leaf level alone outweighs everything above it. - corollary
[P]➔ ➔ strict, -independent: halving work totals the top level. Both corollaries are substitutions, not new inductions. - Induction blueprint
[C]➔ base → assume → prove by adding the -th term to the assumed closed form and re-factoring · precondition: the inductive step must cite the hypothesis explicitly; algebra alone is not a proof. - Induct over the DOMAIN, not
[C]➔ a recurrence in exists only at , so the successor of is : prove , never · precondition: state the restriction explicitly — it is a marked step, and the closing move is always . - Fibonacci doubling identities
[D]➔ · , both read off via · precondition: indexing, and eliminate with · consequence: the index halves ⟹ depth ➔ Fibonacci Sequence.
3️⃣ Recurrence Solving — Telescoping (W1)
Pipeline [P]: pseudocode → recurrence relation → complexity.
MANDATED EXAM FORMAT — Steps 0→6b, write all of them [P] (marks are for the steps, not the answer — full worked exemplar in Solving Recurrences (Telescoping))
0 levels at · 1 substitute in, simplify a little (keep visible) · 2 pattern ➔ general · 3 base ➔ · 4 back-substitute ➔ closed form · 5 complexity · 6a verify at · 6b verify by substituting the closed form into the original RHS (needs ).
Stage 0 — writing the recurrence off the code (where the marks are actually lost)
- Piecewise, with symbolic constants
[P]➔ base for · general for · precondition: is the guard threshold in the source (if n < 3⟹ ), not a reflexive . - counts INVOCATIONS, not coefficients
[P]➔2 * f(n//3) + 4⟹ ·f(n//3) + f(n//3) + 4⟹ · consequence: vs — same source length, different growth class. - Only shrinking arguments are in scope
[P]➔ the assessed recursions decrease the search space (n-1,n//2,n//3); recursions whose argument grows in value are out of assessment scope. - Threshold base shifts by a constant
[C]➔if n < 3with shrink ⟹ — solve with the real threshold, discard the constant at the end. - Method scope — telescoping is the required one
[P]:
| Telescoping | Master Theorem | |
|---|---|---|
| divide | ✅ | ✅ |
| shrink-by-one | ✅ | ❌ no case fits |
| Bound yielded | closed form ⟹ | only |
| Assessment | required | supplementary |
| Recurrence | Depth | Accumulates | Closed form |
|---|---|---|---|
| constants | |||
| arithmetic series | |||
| geometric ratio , | |||
| constants | |||
| geometric | |||
| geometric | regime below | ||
| branching tree, nodes |
- Level-sum
[C]➔ — level holds subproblems of size · precondition: subproblems are equal-sized and the combine is . - Regime from the ratio
[C]➔ root-dominated · all levels equal · leaf-dominated . - Worked instances
[P]➔ : · : · : · : · precondition: read off the number of recursive calls, never off the shifts/additions in the combine. - Leaf identity
[D]➔ — the collapse that produces every D&C exponent. - Diagnostic
[P]➔ subtract from the argument ⟹ depth ; divide ⟹ depth . Depth and per-level work are independent choices. - Branching by SUBTRACTION is the exponential case
[P]➔ telescopes cleanly to · precondition: all calls share one argument; has two and must be bounded by the tree instead · contrast: is only — the coefficient on the call is what flips the class. - “Prove by induction” is a DIFFERENT question from Step 6b
[C]➔ the closed form is given, so nothing is telescoped; produce base cited hypothesis step, inducting over the domain (, not ) ➔ §2️⃣. - 🔭 Master Theorem (supplementary — see the scope table above) ➔ for : · · · precondition: the argument must shrink multiplicatively; applying it to yields a wrong answer, not just an unjustified one.
4️⃣ Recursive Time and Space in One Pass (W1)
Protocol [P]: read (recursive calls) + argument shrink + per-call work → recurrence → telescope for time; take the same depth → auxiliary space ➔ Analysing Recursive Algorithms (Time and Auxiliary Space).
- Auxiliary space
[P]➔ never · precondition: siblings run sequentially — one root-to-leaf frame chain is live at a time. - Single-call recursion ⟹ time space class
[P]➔ : / · : / · consequence: only branching () decouples the two columns. - Fibonacci is the decoupling witness
[C]➔ time (counts nodes) but auxiliary (counts height) · precondition: state which of node-count and height you are measuring, or the answer is unmarkable. - Shrinking allocations SUM
[C]➔ Merge Sort scratch ⟹ , not · precondition: the Geometric Series corollary. - Iterative rewrite drops the stack term
[P]➔ same time, auxiliary — why Binary Search and Linear Search are written as loops. powervspower_better[P]➔ ⟹ passx*x, halve ⟹ time and space, against / · precondition: squaring the base is the halving; leavingxalone computes the wrong value.
5️⃣ Divide & Conquer (W1)
- Shape
[P]➔ divide → conquer recursively → combine · precondition: subproblems are independent; overlapping ones recompute exponentially and demand memoisation/DP instead. - Balance sets depth
[C]➔ even halves levels ⟹ · maximally lopsided levels ⟹ · single half with work ⟹ . - Split/combine trade
[C]➔ Merge Sort trivial split / heavy combine · Quick Sort heavy split / trivial combine · Binary Search one subproblem (“decrease and conquer”). - The factor is bought by the combine, not the branching
[D]➔ but . - Adapting D&C to an UNSEEN problem — three questions in order
[P]➔ (1) does the answer decompose additively into within-left within-right cross? (2) is the cross term computable in ? (3) does the per-call work shrink with the subproblem? · consequence: failing (3) is the silent one — see the peak-finding entry below. - Strengthen the recursive contract
[C]➔ make the recursion return more than the answer; Counting Inversions is linear-per-level only because each call also returns its subarray sorted · precondition: the extra guarantee must itself be maintainable in the combine. - Cross-term counting: block, never pairwise
[P]➔ emitting during a merge while is unconsumed retires inversions in one addition · precondition: both runs sorted; a instead counts merge steps, not inversions. - Per-call work must shrink or the level sum won’t decay
[P]➔ 2D Local Maximum (Peak Finding): a middle-column split leaves an block whose deciding scan is still ⟹ ; cutting both axes (cross / window frame) gives , ⟹ . - Discarding subproblems needs an EXISTENCE claim
[C]➔ “a peak of lies inside the kept quadrant, because a strictly-increasing walk from can never re-cross the cross” · precondition: the claim is about the kept region containing an answer, not about the discarded ones being empty — that is the marked sentence. - Two identical recursive calls are a common subexpression
[P]➔POW(x,p/2)*POW(x,p/2)is ;y = POW(x,p/2); return y*yis · consequence: halving bounds the tree’s height, branching fills it — nodes. Same trap in Fibonacci fast doubling.
6️⃣ W1 Algorithm Bounds
| Algorithm | Recurrence | Time (B/A/W) | Auxiliary space | Discriminator |
|---|---|---|---|---|
| Schoolbook multiply | — | all | every digit pair | |
| Naive D&C multiply | all | ⟹ no gain | ||
| Merge Sort | all | scratch stack | order-independent, stable | |
| Quick Sort | avg | / W | stack | pivot quality |
find_min (iterative) | — | all | — in-place | no early exit ⟹ B W |
build_list(n) | — | all | allocated | input is a number, output is the cost |
| Linear Search (recursive) | / / | frames | early return on hit | |
| Binary Search (iterative) | / / | · recursive: frames | early return on hit; input space | |
f(n) = 2*f(n//3) + 4 | all | frames | one call site | |
f(n) = f(n//3)+f(n//3)+4 | frames | two call sites — leaf-dominated | ||
power | all | frames | decrement | |
power_better | all | frames | squares the base | |
power_naive (call written twice) | all | frames | halving buys nothing — binary tree | |
power_fast (y bound once) | all | frames | cut from to | |
naive fibonacci | all | frames | nodes vs height | |
| Counting Inversions | all | scratch | recursion also returns sorted; output may be | |
| 2D Local Maximum (Peak Finding), gradient walk | — | / — / | ridge adversary | |
| 2D Local Maximum (Peak Finding), column split | , fixed | all | frames | scan length never shrinks |
| 2D Local Maximum (Peak Finding), window frame | all | frames | root-dominated; reads cells | |
| Range report, scan | — | touches all | ||
| Range report, Binary Search scan | — | optimal — meets |
- Asymptotic win ≠ faster in practice
[C]➔ a lower exponent bought with extra additions/shifts carries a large constant, so the “worse” algorithm wins on small · consequence: an asymptotic claim is never a claim about a particular input size. - Merge stability
[C]➔ the tie-breaka[ia] <= a[ib]emits from the left half · precondition: strict<breaks stability.
7️⃣ Proof of Correctness (W2)
Correctness is two obligations. An invariant with no termination argument proves only partial correctness; a termination argument with no invariant proves only that it stops — possibly with the wrong answer.
- The answer template
[P]➔ (1) loop invariant, quantified over the counter · (2) termination: the measure that strictly decreases · (3) one line: invariant postcondition · precondition: the invariant must mention the data, not just the counter — “iincreases” is not an invariant. - Three-part induction
[P]➔ initialization (base) · maintenance (step) · termination (exit) ➔ Invariant. - Termination template
[P]➔ domain is finite · counter starts at a known point · every iteration moves it monotonically toward the bound · recursive variant: name the argument that shrinks and the base case it reaches. - Variant
[C]➔ with · precondition: strictly — a step that may leave unchanged is where infinite loops live. - Design order
[C]➔ define the invariant, then code to it; keep it the weakest statement that implies the postcondition — extra clauses are extra proof burden, no extra marks. - Exam shape
[P]➔ “(1 mark) write a loop invariant for Floyd–Warshall that shows it computes all-pairs shortest distances” — prose algorithm in, one quantified sentence out.
| Algorithm | Loop invariant | Termination measure |
|---|---|---|
find_min | my_min array[0…index] | index starts at , increments, array finite |
| Selection sort | my_list[0…i-1] sorted AND all of my_list[i…N] | and only increment, both reach the end |
| Insertion sort | my_list[0…i-1] sorted (not final) | increments; inner decreases, bounded by |
| Binary Search | key in array[0…N] key in array[lo…hi] | must strictly shrink ⟹ the bug vector |
- The
lo = midhang[P]➔ at : , solo = midis a no-op ⟹ never terminates · fix:mid + 1, or guardwhile lo < hi - 1with an exclusivehi = len(array)so the space shrinks to size .
8️⃣ Sorting — the Four-Axis Suite (W2)
Rank every sort on correctness · time (B/A/W) · auxiliary space · stability. Two multipliers are dropped constantly: the comparison cost and the recursion stack.
- is a claim about a CLASS
[P]➔ it binds comparison-based sorts only · consequence: Merge Sort/Heapsort are provably optimal there; Counting Sort/Radix Sort escape it by assuming bounded integer keys, not by beating it. - Comparison cost multiplies EVERYTHING
[P]➔ comparing words/tuples costs ⟹ elementary, merge · precondition: declare constant or carry it. - Recursion stack is auxiliary space
[P]➔ live frames, if a frame holds words ⟹ recursive sorts are not in-place even with zero heap allocation · consequence: in-place auxiliary, so the iterative rewrite is the only route. - Selection sort has no best case
[C]➔ the minimum must be located in full every pass ⟹ B A W ; unstable via the long-distance swap ([4a,2,3,4b,1][1,2,3,4b,4a]). - Insertion sort is stable because it SHIFTS
[C]➔ equal keys are never moved past each other; best when the innerwhilenever fires.
| 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 |
- Counting Sort phases
[P]➔ max → allocate → tally (key is the index) → rebuild · precondition: is the key range; quoting requires stating that is capped (alphabet , digits ). - Stability is engineered, not inherited
[P]➔ prefix-sum positions:position[first] = 1, , then scan the input forwards writingoutput[position[key]]and incrementing. - Bucket space is , NOT
[P]➔ lecturer-flagged very common misconception — buckets partition the input, , so slots and payloads add. - Radix Sort stable counting sorts
[P]➔ LSD (rightmost) first · precondition: each pass must be stable, or the order won by lower-significance passes is destroyed and nothing later repairs it. - The notation clash
[C]➔ in counting sort is the maximum key; in radix sort is the base (distinct symbols per column) — name which before quoting. - Auxiliary carries no
[D]➔ the count/position/output arrays are reused each pass ⟹ ; only the input is . - vs base trade
[C]➔ — raising shrinks but grows the term and auxiliary · precondition: worth it while . - “Radix is ” needs a hypothesis
[D]➔ true only for capped key width; distinct base- keys force , recovering . - Ragged keys
[C]➔ pad to a common width with a filler that sorts below every real symbol · precondition: right-aligned padding gives numeric order, left-aligned gives lexicographic — they differ. - Base choice is what buys linearity
[P]➔ pick so the per-pass stays ; then with constant · precondition: makes the count array dominate and the sort is linear in , not . - Digit extraction
[P]➔ column of key in base is · consequence: per digit, no string conversion. max()serves different masters[P]➔ Counting Sort needs it to size the count array; Radix Sort sizes that from the base and needsmaxonly for the column count · lecturer-flagged as the recurring code-review error.- Negative keys ⟹ offset map
[C]➔ store at , range , and add back on rebuild · consequence: the bound is driven by the range, not the maximum. - Bucket drain must be
[C]➔extend(), neverpop(0)(shifts, each ⟹ rebuild) · alternative: circular queue / deque if FIFO removal is genuinely required. - Which counting-sort variant?
[P]➔ unstated ⟹ bucket variant; a question naming a count array and a position array wants the prefix-sum variant — that pairing is its signature (PT-01).
9️⃣ Quicksort, Selection and the Applied Suite (W3)
Every W3 bound is a pair: an expected value and a worst case that differ. An answer that quotes one without naming which is unmarkable ➔ §1️⃣ bound ≠ case.
-
Partition contracts differ — and so do the calls
[P]➔ Lomuto returns the pivot’s final index ⟹ recurse(start, j-1)and(j+1, end)· Hoare returns a split point ⟹ recurse(start, j)and(j+1, end)· precondition: copying Lomuto’sj-1onto Hoare drops an element and the sort silently loses data. -
Schemes differ in WRITES, not comparisons
[C]➔ all make comparisons per level; Hoare makes fewer swaps · consequence: the choice matters when records are large, not when keys are integers. -
3-way (Dutch flag) for duplicates
[C]➔ split into and recurse on the outer two ⟹ depth for distinct keys, on all-equal input · precondition: a 2-way split can never retire equal keys, so they recur forever. -
Constant-FRACTION splits are still
[P]➔ a fixed split gives depth · consequence: needs a constant-size split at every level, not merely an unbalanced one. -
Randomisation vs guarantee
[P]➔ a random pivot makes the bad input unconstructible (expected , worst case still ); Median of Medians makes it impossible (worst case ) · precondition: name which claim you are making — this is the W3 exam hinge. -
Quicksort auxiliary space is worst, if engineered
[P]➔ recurse the smaller partition first and loop on the larger ⟹ depth regardless of pivot quality. -
Quicksort stability “depends on the partition”
[C]➔ in-place swapping is unstable; an out-of-place partition preserving input order is stable at per level. -
Quickselect quicksort minus one call
[P]➔ after partition at : return · recurse left · recurse right, unchanged under absolute indices · consequence: level costs become ⟹ Geometric Series ⟹ expected. -
Quickselect is auxiliary, quicksort is not
[C]➔ the single call is a tail call ⟹ rewritable as awhileoverlo/hi· precondition: quicksort’s first call has work pending after it, so its frames stay live. -
Median of Medians recurrence
[D]➔ with · precondition: the fractions must sum to strictly less than — groups of give . Lecturer-stated as historically not examinable in the exam; quiz-live. -
Forcing stability costs space, never time
[P]➔ parallel index list consulted only when , compared as integers in ⟹ every time bound unchanged; auxiliary , total still . -
Shifting is stable, long-distance swapping is not
[C]➔ bubble/insertion/merge shift ⟹ stable; selection/heap/quicksort hurdle equal keys ⟹ unstable. -
Comparisons swaps
[C]➔ nothing is swapped that was not first compared · use: a self-check on a derived count. -
An integer comparison is by HARDWARE
[C]➔ one machine instruction on a fixed-width word; a -character string has no such instruction ⟹ · consequence: the item type, not the algorithm, decides whether may be dropped. -
Best worst is a diagnostic
[P]➔ it holds exactly when there is no early termination and item values cannot steer control flow (selection, Merge Sort) · consequence: bubble/insertion fail the first, Quick Sort the second. -
K-way Merge
[P]➔ naive “minimum of heads” scan ⟹ min-Heap of the heads , auxiliary · invariant: at iteration the root is every unconsumed item, because each list is sorted so its head is its own minimum. -
Heap entries carry
[C]➔ the id is what makes the refill · precondition: the heap never exceeds size ; seeding all items is heapsort, not a merge. -
Online vs offline decides admissibility BEFORE complexity
[P]➔ online act on each arrival with no view of the future, answer valid at every instant · consequence: Quickselect is and still unusable on a stream; insertion sort and [[Heap|add/rise]] are online, Merge Sort and bottom-upbuild_heapare not. -
smallest ⟹ size- MAX-heap
[P]➔ root largest admitted the eviction threshold; arrival root ⟹ reject in , else evict root and insert ⟹ time, space · mirror: largest ⟹ min-heap. Always heap the opposite extreme to the one collected. -
Sorting is preprocessing, not a goal
[C]➔ it buys adjacency (grouping, dedup) and access (Binary Search) · precondition: it is only worth if the follow-up pass gets cheaper. -
Dedup after sorting is two pointers
[P]➔read/write, overwrite never shift ⟹ · consequence: shift-on-delete is per removal ⟹ . -
An “in-place” spec PICKS THE SORT
[P]➔ the compaction is already auxiliary, so Heapsort is the only valid sort (Merge Sort scratch, Quick Sort stack) · consequence: naming the sort is the marked step, not the loop. -
Optimality by REDUCTION
[C]➔ split a length- sequence into singleton lists and -way merge them ⟹ it is a comparison sort ⟹ inherits ⟹ no comparison-based merge beats · use: the general move — simulate a problem whose bound you already know. -
Ragged-string radix in
[D]➔ ( strings, longest, lengths) counting-sort by length ascending , then sweep moving a pointer so have length , subsorting only that window · precondition: ascending, so a prefix sorts before its extension (catbeforecats); naive padding is . -
The constant-factor radix base
[D]➔ minimise ; for the optimum is ( passes) · precondition: pick with — digit extraction becomes shift-and-mask and no column is ragged. -
The comparison model proves , NEVER
[D]➔ insertion sort with a Binary Search insertion point makes comparisons — optimal — yet runs in because it still shifts · consequence: an optimal comparison count is not an optimal running time; use the model for lower bounds only. -
“In-place” is a claim about the COST MODEL
[D]➔ the unit’s auxiliary means machine words; under strict RAM accounting, indexing elements needs -bit pointers, so the definition is relaxed to , or excluding pointers, or · precondition: say which you mean before claiming in-place.
| W3 algorithm | Time (B/A/W) | Auxiliary space | 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, large constant | |
| Quickselect (random pivot) | / / | iterative | No | one rank; destroys input order |
| Quickselect Median of Medians | all | No | linear worst case selection | |
| K-way Merge (min-heap) | all | Yes | space ⟹ external sorting | |
| K-way Merge (scan heads) | all | Yes | only for | |
| Size- heap ➔ Online Algorithm | all | Yes | unknown/unbounded, or a memory cap |