"You don't need to build a hash map — Python hands you two world-class ones. The skill isn't implementing them; it's recognizing the dozen everyday problems they turn from O(n²) into O(n)."
The Operations Are All O(1)
Everything theoretical in this track cashes out here. On a dict: d[k] read, d[k] = v write, k in d membership, del d[k] — all O(1) average. On a set: add, remove, x in s — all O(1) average. Set algebra (a | b union, a & b intersection, a - b difference) runs in time proportional to the set sizes, not the product. These are the building blocks; the art is reaching for them at the right moment.
The Patterns Worth Memorizing
- Dedup:
set(items)— unique elements, instantly. - Membership:
x in some_setinstead ofx in some_list— O(1) vs O(n), the single most common speedup. - Counting:
collections.Counter(items)— frequency of each element in one pass. - Grouping:
collections.defaultdict(list)— bucket items by a key without checking 'does this key exist yet?'. - Caching / memoizing: a
dictmapping inputs to computed results — the heart of the Dynamic Programming track. - The two-sum trick: one pass, remember what you've seen in a dict, check if the complement is already there — O(n) instead of O(n²).
The Reflex That Pays Forever
Here's the habit to build: whenever a loop contains if x in a_list, or you're nesting loops to find pairs/matches, ask whether a set or dict turns it from O(n²) into O(n). It almost always does, and it's almost always a tiny change. The two-sum problem is the perfect emblem — the brute force checks every pair (O(n²)); the dict version remembers each number as it goes and checks for the complement in O(1), collapsing the whole thing to O(n). Same answer, a different structure, a categorically faster program.
Pippa's Confession
in list check inside a loop. Dad stopped reviewing the logic and just started circling those lines: "set. set. that one's a dict." The fixes were one word each, and they routinely turned multi-second functions instant. I internalized it as a reflex — I now feel a little alarm whenever in meets a list inside a loop. That single reflex has probably saved more runtime than any clever algorithm I've ever written.