7 routes42 sections324 units

Unit 1.5 · about 4 h

92 / 324

Hash tables: collisions, load factor, resizing and tombstones

Hash maps are the default index, counter and cache. Their average is excellent and their worst case is a security incident; both follow from the load factor.

  • explain
  • implement

You can now

  • Explain chaining and open-addressing costs in the load factor, including the \(1/(1-\alpha)\) blowup.
  • Implement a hash table that resizes at a stated load factor, with deletion that preserves lookup.
  • Predict adversarial degradation and name the defense (randomized hashing).

Covers

  • Hashing, collisions, load factor, resizing and tombstones

Study, in this order

4 steps

  1. Hash maps and hash sets
    DSA Handbook - Foundations and linear patterns

    What invariant the average-case bound depends on (\(\Theta(1+\alpha)\)); LC 1 value-to-index; LC 49 signature keys; LC 242 counters; What it actually costs (the double-plus-rehash resize contract)

  2. Hash collisions and the load factor
    DSA Handbook - Foundations and linear patterns

    Two strategies, one contract; What it costs to grow; When the contract breaks: LC 128 in two complexities; How the 28C3 attack worked, and what fixed it (SipHash, PEP 456); A second example: LC 380's pointer-redirection trick

    Depth · Treat the CPython probing recurrence as a reading guide for the source item below, not as a substitute for it.

  3. Lecture 5: Hash Tables, Sections 5.1 to 5.5 and 5.8 to 5.10
    Algorithms lecture notes - amortized analysis and hashing

    5.2 The Importance of Being Random; 5.3 universal and near-universal definitions; 5.4 Chaining (expected \(O(1+\alpha)\)); 5.5 multiplicative hashing with Theorems 1 and 2; 5.8 Open Addressing (expected at most \(1/(1-\alpha)\)); 5.9 Linear and Binary Probing

    Depth · Read the statements of 5.6 Balls and Bins and 5.7 Perfect Hashing; skip their proofs.

  4. CPython dict internals
    CPython source - list and dict objects

    USABLE_FRACTION (currently two-thirds) with its definition comment; the perturbation-probing comment (j = (5*j) + 1 + perturb); dummy (tombstone) entries on deletion

    Depth · Find the three definitions; do not read the whole file.

Focus on

  • \(\alpha = n/m\) governs everything: chaining \(\Theta(1+\alpha)\), open addressing \(1/(1-\alpha)\); CPython resizes past \(2/3\).
  • Resize doubles and rehashes every entry: an \(O(n)\) event, amortized \(O(1)\) by the unit-2 argument.
  • Deletion must leave a tombstone: marking the slot empty would cut probe chains and lose keys.
  • Deterministic string hashing is attackable (the 2011 HashDoS); Python seeds SipHash per interpreter (PEP 456).

Reproduce closed-book

Insert ints 0 to 49 into an empty dict on Python 3.13.14, recording sys.getsizeof after each insert. The first insert allocates the 8-slot table; assert the later size steps at \(n\) = 6, 11, 22 and 43, confirming the two-thirds rule. Then delete two keys and assert the byte size and the remaining key order are unchanged.

Traps

  • Reading insertion order as sorted order; dicts remember arrival, not rank.
  • Checking the map after storing on Two Sum style lookup: store-then-check matches an element with itself on inputs like [3, 3].
  • Assuming worst-case \(O(1)\): adversarial keys drive any fixed hash to \(O(n)\) chains.

Practice

LeetCode 706: Design HashMap

Attempt cold with hidden tags. Implement put, get and remove with chaining or open addressing plus a load-factor resize. Add randomized put/get/remove histories checked against a dict oracle. Judge with the Example operation sequence.

After submitting, read the AlgoMaster Design HashMap write-up (https://algomaster.io/learn/dsa/design-hashmap) and the handbook hash-collisions chapter for the resize contract.

Self-test

  1. Derive the expected cost of a chained lookup.

  2. Why does CPython resize at the 6th insert into an 8-slot table?

  3. What breaks if deletion marks the slot empty instead of dummy?

  4. State universal hashing in one line and why it helps.

Completion criterion

Stop when

Your resize script asserts the 6/11/22/43 steps, and your HashMap passes 200 randomized histories against the dict oracle.

Mark passed, then open 1.6 Only mark this when you can do it without notes.

Leads to

Comes after

Resources for this unit

  • DSA Handbook - Foundations and linear patterns
    Handbook Academyprimarycourse
    Study Part 0, Part 1, Part 3 and Part 4 in order, plus the Part 5 Linked-list fundamentals chapter. Use the routing-rule pages for arrays versus lists, map choice, stack versus queue, two pointers, sliding windows and prefix methods before seeing solved code.
  • Algorithms lecture notes - amortized analysis and hashing
    Jeff Ericksonsupporttheory
    Use note 9 Amortized Analysis for the summation, taxation, charging and potential-function proofs, and note 5 Hashing for chaining, universal hashing and open-addressing analysis, when the handbook treatment is too brief for a proof.
  • CPython source - list and dict objects
    Python Software Foundationreferencereference
    Read list_resize in Objects/listobject.c for the growth formula and pattern comment, and the USABLE_FRACTION definition, perturbation-probing comment and dummy-entry handling in Objects/dictobject.c. Read the cited functions and comments only.

Also in this section

  • AlgoMaster DSA - linear structures slice
    AlgoMasterrequiredpractice
    Attempt Design HashMap, Longest Substring Without Repeating Characters and Sliding Window Maximum cold. Hide tags, state the invariant first, and add randomized operation histories to Design HashMap.
  • MIT 6.042J - asymptotics and invariants
    MIT OpenCourseWaresupporttheory
    Use the asymptotics, state-machine invariants and proof-method readings when a cost or correctness argument is weak. Solve only the matching problems.
  • Algorithmica - memory and data layout
    Sergey Slotinsupportapplication
    Read the memory hierarchy, cache and complexity-model chapters, then measure one contiguous-versus-linked and one hash-versus-ordered workload crossover.
  • NeetCode - unseen linear problems
    NeetCodeoptionalassessment
    Use only for two tag-hidden transfer problems after the AlgoMaster slice. Do not start another full roadmap or watch a solution before the attempt is complete.
  • Hypothesis documentation - Quickstart and stateful testing
    Hypothesissupportreference
    Follow Quickstart for @given strategies and the pytest combination, Configuring test settings for max_examples and derandomize, then Rule-based state machines (rule, precondition, invariant, run_state_machine_as_test) for randomized operation histories against dict and deque oracles.

Quick find

Search Michi

Type to search every route, section, unit, topic and resource.

Enter opens the first result Esc closes

Reference

Keyboard shortcuts

n
Continue to the first unit not passed
j / k
Next / previous unit
1 2 3
Toggle learned, practised, passed
/
Open search
?
Show this help
Esc
Close open panels