Algorithms handbook

A free, structured course on data structures and algorithms: Competitive programming intro, Foundations, NP-hardness & intractability, Arrays & strings, Bit…

Competitive programming intro

The judge workflow, C to C++ bridge, constraint reading, submissions, verdicts, and templates.

Foundations

How to think about algorithms and measure what they cost.

  • Big-O in one sitting — What Big-O measures, the classes worth knowing, and how to derive one from a loop.
  • Space complexity — Memory has a Big-O too — auxiliary space, recursion stacks, input space, and trade-offs.
  • Time complexity in practice — Best, average, worst, amortized time, and what Big-O deliberately ignores.

NP-hardness & intractability

The complexity landscape beyond Big-O: P, NP, NP-complete, reductions, and what to do when a problem is hard.

Arrays & strings

Contiguous memory, O(1) access, and the two-pointer trick.

  • Arrays & two pointers — Why indexing is O(1), why inserting in the middle isn't, and the two-pointer pattern.
  • The sliding window — Turn an O(n·k) scan into a single O(n) pass by reusing the overlap.

Bit manipulation

Think in binary: operators, the standard bit tricks, and subsets-as-integers bitmask DP.

Searching

Finding a value in a collection — and why sorted data changes everything.

  • Linear search — The baseline: check every element until you find the target.
  • Binary search — Halving a sorted array each step to find a value in O(log n).
  • Ternary search — Splitting search into thirds, why it is O(log n), and why binary still usually wins.

Sorting

Putting things in order — five classic algorithms, watched live.

  • Meet sorting — Why sorting matters, what makes one algorithm better, and a playground with all five.
  • Bubble sort — The simplest sort, and a clean derivation of why it's quadratic.
  • Merge sort — Divide in half, sort each half, merge — and solve the recurrence for O(n log n).
  • Quick sort — Partition around a pivot, recurse — fast on average, with a worst case to respect.
  • Insertion & selection sort — Two more O(n²) sorts — one shines on nearly-sorted data, one minimises writes.

Recursion

Functions that call themselves — base cases, the call stack, and trees of calls.

  • Recursion & the call stack — Base case, recursive case, and how each call lives on the stack until it returns.
  • Divide & conquer — Split a problem, solve smaller copies, and combine the answers with recurrence maths.
  • Backtracking — Explore choices, and undo them when they hit a dead end.

Linked lists

Nodes connected by pointers — O(1) insertion, but no random access.

  • Pointers first (C++) — The memory model behind linked lists: addresses, dereferencing, nullptr, and ownership.
  • Linked lists — How nodes and pointers trade away indexing for cheap insertion at the ends.
  • Stacks & queues from a list — The same nodes build two different structures — depending on which end you use.

Stacks & queues

Two restricted lists: last-in-first-out and first-in-first-out.

  • Stacks (LIFO) — Push and pop from one end — the structure behind undo, parsing, and the call stack.
  • Queues (FIFO) — Add at the rear, remove from the front — fairness, and breadth-first search.
  • Where they shine — Bracket matching, undo histories, and the searches you've already met.

Hashing & hash tables

Turning keys into bucket indices for O(1) average lookup.

  • Hash tables — How a hash function gives near-constant-time lookup, and what happens on a collision.
  • Sets & the two-sum trick — How a hash set turns an O(n²) search into a single O(n) pass.

Trees & BSTs

Hierarchical structure, and the binary search tree's ordered layout.

Tree traversals

The four ways to visit every node — and what each one is good for.

Heaps & priority queues

A complete binary tree in an array that always hands you the min (or max) in O(log n).

Graphs & representations

How to store a graph, traverse it with BFS/DFS, and order or component-split it.

Pathfinding & Graphs

Searching mazes and networks: BFS, DFS, Dijkstra, A*, Bellman-Ford and Floyd-Warshall.

  • Searching a grid — How the four classic searches explore space, and what 'shortest path' really means.
  • Weighted graphs: Dijkstra & A* — Shortest paths with non-negative weights, priority queues, and admissible heuristics.
  • Bellman-Ford — Shortest paths with negative edges, plus negative-cycle detection.
  • Floyd-Warshall — All-pairs shortest paths with a compact dynamic-programming recurrence.

Minimum spanning trees

Connect every vertex with minimum total edge weight using Kruskal, Prim, and DSU.

  • Spanning trees and MSTs — Tree vs spanning tree, why cycles are unnecessary, and what a minimum spanning tree optimizes.
  • Kruskal and DSU — Sort edges by weight, accept safe edges, and use Union-Find to detect cycles.
  • Prim's algorithm — Grow one connected tree with the cheapest edge crossing the current cut.

Greedy algorithms

Make the locally best choice and never look back — when an exchange argument proves it's optimal.

Divide & conquer

Split a problem into independent subproblems, solve them, and combine — with the Master Theorem to read the cost.

Dynamic programming

Solve overlapping subproblems once and reuse the answers — 1D and 2D tables.

Strings & pattern matching

Find a pattern inside a text fast: the naive scan, KMP's failure function, and rolling hashes.

Math for algorithms

The number theory and combinatorics that show up in contests: gcd, modular arithmetic, primes, and nCr.

Game theory

Impartial games: winning/losing positions, Nim, and Sprague–Grundy numbers.