"Sometimes the smartest move is to flip a coin. Randomness can dodge worst-case inputs an adversary would exploit, and let you sample an answer when computing the exact one is impossible. Giving up a little certainty buys a lot of speed."
Randomness as a Tool, Not a Bug
Randomness can break the correlation between a fixed input and an algorithm's choices: randomized quicksort still has an O(n²) worst case, but runs in expected O(n log n). CPython also salts many string hashes to make crafted collision attacks harder, though this is a runtime defense rather than a universal property of hashing. Sampling is useful not only when exact computation is impossible, but whenever an exact answer is possible yet too costly and a controlled estimate is sufficient.
Two Flavors of Randomized Algorithm
- Las Vegas: always returns the correct answer, but the runtime is random. Randomized quicksort is the classic — the output is always sorted; only the speed depends on luck (and is excellent in expectation). You never get a wrong answer, just occasionally a slower run.
- Monte Carlo: accepts error probability or approximation error in exchange for a bounded work budget. It need not take exactly the same fixed time on every input.
Knowing which guarantee you have — always-right-maybe-slow versus always-fast-maybe-wrong — tells you whether a randomized algorithm is safe for your use.
The Gem: Reservoir Sampling
The most elegant randomized algorithm is reservoir sampling: pick a uniformly-random item from a stream of unknown, possibly enormous length, in O(1) space and one pass. The trick: keep the current pick; when the i-th item arrives, replace your pick with it with probability 1/i. When the stream ends, every item — first or billionth — had an equal chance of being chosen, provably. It's how you sample a random line from a file too big to hold in memory, or a random log entry from an endless feed. One variable, one pass, perfect uniformity, no idea how long the stream is. Pure randomized magic.