AAI Agentic Handbook
Problem 93 · Data Engineering & Streaming

HyperLogLog Cardinality Estimation

HardClassic DSA & systems
01Problem

Implement a simplified HyperLogLog that estimates the number of distinct items in a stream, supports merging, and corrects for small cardinalities.

02Key insight

Hash each item; the first p bits pick one of m=2^p registers and each register keeps the max leading-zero rank of the remaining bits. The harmonic mean of 2^-register gives the estimate with ~1.04/sqrt(m) relative error; fall back to linear counting when many registers are empty. Merge = elementwise max, which is why APPROX_COUNT_DISTINCT parallelises.

03Solution

Try it first.

TimeO(1) per add, O(m) per count
SpaceO(m) bytes (4 KB at p=12)
tests.py · 3 passing
tests.pypython14 lines
h = HyperLogLog(p=12)
for i in range(50000):
    h.add(f"user-{i}")
    h.add(f"user-{i}")  # duplicates do not change the estimate
assert abs(h.count() - 50000) / 50000 < 0.05
small = HyperLogLog(p=12)
for i in range(100):
    small.add(i)
assert abs(small.count() - 100) < 5
x, y = HyperLogLog(10), HyperLogLog(10)
for i in range(0, 6000): x.add(i)
for i in range(3000, 9000): y.add(i)
x.merge(y)
assert abs(x.count() - 9000) / 9000 < 0.1
04Staff-level follow-up

Why can't you compute distinct-count of an intersection reliably with HLL? Only union merges are native; intersection via inclusion-exclusion compounds errors badly for small overlaps - use MinHash/theta sketches when set operations matter.