Part 9 · 1 chapters · ~8 min

Randomised Algorithms

Why randomness helps (expected performance, avoiding adversarial inputs), quickselect and randomised quicksort, reservoir sampling, shuffling correctly (Fisher-Yates), Monte Carlo versus Las Vegas algorithms, probabilistic data structures (Bloom filters, HyperLogLog, count-min sketch, skip lists), and seeding for reproducibility.

16

Randomness as a tool

code
// Fisher-Yates shuffle: every permutation equally likely (sort(() => Math.random() - 0.5) is biased)
function shuffle<T>(a: T[]): T[] { for (let i = a.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [a[i], a[j]] = [a[j], a[i]]; } return a; }

// reservoir sampling: a uniform sample of k items from a stream of unknown length, O(k) memory
function reservoir<T>(stream: Iterable<T>, k: number): T[] {
  const r: T[] = []; let n = 0;
  for (const x of stream) { n++; if (r.length < k) r.push(x); else { const j = Math.floor(Math.random() * n); if (j < k) r[j] = x; } }
  return r;
}
// quickselect: the k-th smallest in O(n) expected (median latency without full sorting)
kindguaranteeexample
Las Vegasalways correct, running time is randomrandomised quicksort, quickselect
Monte Carlofixed time, answer correct with high probabilityMiller-Rabin primality test, Bloom filters (false positives)
probabilistic structuressmall memory, bounded errorHyperLogLog (count distinct users in 12 KB), count-min sketch (heavy hitters), skip lists (Redis sorted sets)

Use a seeded generator in tests and simulations so failures replay (Distributed Systems part 13). Use crypto.getRandomValues, never Math.random, for anything security-related (tokens, OTPs).