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 recurrencetelescope to a level-sumread 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]AnalysesW1 witness
Bestcheapest input of size naive D&C multiply ➔ best worst, no branching
Worstdearest input of size quicksort, extreme pivot ➔
Averageexpectation over an input distributionquicksort, random pivot ➔
Amortised [D]worst-case total over a sequence lengtha 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 < 3 with shrink ⟹ — solve with the real threshold, discard the constant at the end.
  • Method scope — telescoping is the required one [P]:
TelescopingMaster Theorem
divide
shrink-by-one❌ no case fits
Bound yieldedclosed form ⟹ only
Assessmentrequiredsupplementary
RecurrenceDepth AccumulatesClosed 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 spaceAnalysing 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.
  • power vs power_better [P] ⟹ pass x*x, halve time and space, against / · precondition: squaring the base is the halving; leaving x alone 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*y is · consequence: halving bounds the tree’s height, branching fills it — nodes. Same trap in Fibonacci fast doubling.

6️⃣ W1 Algorithm Bounds

AlgorithmRecurrenceTime (B/A/W)Auxiliary spaceDiscriminator
Schoolbook multiply allevery digit pair
Naive D&C multiply all ⟹ no gain
Merge Sort all scratch stack order-independent, stable
Quick Sortavg / W stackpivot quality
find_min (iterative) allin-placeno early exit ⟹ B W
build_list(n) all allocatedinput is a number, output is the cost
Linear Search (recursive) / / framesearly return on hit
Binary Search (iterative) / / · recursive: framesearly return on hit; input space
f(n) = 2*f(n//3) + 4 all framesone call site
f(n) = f(n//3)+f(n//3)+4 framestwo call sites — leaf-dominated
power all framesdecrement
power_better all framessquares the base
power_naive (call written twice) all frameshalving buys nothing — binary tree
power_fast (y bound once) all frames cut from to
naive fibonacci all framesnodes vs height
Counting Inversions all scratchrecursion also returns sorted; output may be
2D Local Maximum (Peak Finding), gradient walk / — / ridge adversary
2D Local Maximum (Peak Finding), column split, fixed all framesscan length never shrinks
2D Local Maximum (Peak Finding), window frame all frames root-dominated; reads cells
Range report, scantouches all
Range report, Binary Search scanoptimal — 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-break a[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 — “i increases” 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.
AlgorithmLoop invariantTermination measure
find_minmy_min array[0…index]index starts at , increments, array finite
Selection sortmy_list[0…i-1] sorted AND all of my_list[i…N] and only increment, both reach the end
Insertion sortmy_list[0…i-1] sorted (not final) increments; inner decreases, bounded by
Binary Searchkey in array[0…N] key in array[lo…hi] must strictly shrink ⟹ the bug vector
  • The lo = mid hang [P] ➔ at : , so lo = mid is a no-op ⟹ never terminates · fix: mid + 1, or guard while lo < hi - 1 with an exclusive hi = 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 inner while never fires.
AlgorithmBestAverageWorstAuxiliaryStableIn-place
SelectionNoYes
InsertionYesYes
HeapsortNoYes
Merge SortYesNo
Quick SortDependsNo
Counting Sort · stableengineeredNo
Radix SortrequiredNo
  • 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 writing output[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 needs max only 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(), never pop(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’s j-1 onto 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 a while over lo/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-up build_heap are 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 (cat before cats); 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 algorithmTime (B/A/W)Auxiliary spaceOnline?Discriminator
Quick Sort (random pivot) / / smaller-first · naiveNosmallest constant of the sorts
Quick Sort Median of Medians allNoworst case eliminated, large constant
Quickselect (random pivot) / / iterativeNoone rank; destroys input order
Quickselect Median of Medians allNolinear worst case selection
K-way Merge (min-heap) allYes space ⟹ external sorting
K-way Merge (scan heads) allYesonly for
Size- heap ➔ Online Algorithm allYes unknown/unbounded, or a memory cap