Interactive visualization of hashing, collision resolution (chaining & probing), load factor, and interview patterns.
Learning Progress. Work top to bottom: theory → collision handling → the interactive bucket visualizer → patterns → cheat sheet → interview prep. Pin the visualizer (button top-right of the panel) to keep it on screen while you read.
Theory & Fundamentals
What is a Hash Table?
A Hash Table maps keys to values using a hash function that turns a key into an array index (a bucket). Done well, insert, delete, and lookup are O(1) average.
The catch is collisions: two keys hashing to the same bucket. How you resolve them (chaining vs open addressing) and your load factor decide real-world performance.
The hash function
// map key → bucket index
index = hash(key) % capacity
// good hash: fast, uniform, deterministic // load factor α = n / capacity // resize (rehash) when α > ~0.75
Why Hash Tables? They turn O(n) lookups into O(1): the single most common way to speed up an algorithm. Two Sum, frequency counts, dedup, caches, sets, symbol tables — all hash tables underneath.
Collision Resolution
🔗
Separate Chaining
Each bucket holds a linked list (or vector) of entries that hash there.
Use: simple, handles high load factor. std::unordered_map.
➡️
Linear Probing
On collision, step to the next slot (i+1, i+2…) until an empty one.
Use: cache-friendly, but clustering.
🔢
Quadratic / Double Hash
Probe by i², or use a second hash for the step, reducing clustering.
Use: open addressing with better spread.
Terminology
Hash Function
Maps a key to an integer index, ideally uniformly.
Bucket / Slot
An array cell where entries hashing to that index live.
Collision
Two distinct keys mapping to the same bucket.
Load Factor (α)
n / capacity. High α → more collisions → slower ops.
Rehashing
Growing the table and re-inserting all keys when α gets high.
Clustering
Consecutive filled slots in probing, hurting performance.
Complexity Summary
Insert
O(1)*
Average; O(n) worst with bad hashing.
Search
O(1)*
Average; O(n) if all keys collide.
Delete
O(1)*
Average constant time.
Rehash
O(n)
Occasional, amortized into O(1) inserts.
Space
O(n)
Plus empty-slot overhead (α < 1).
Ordered iterate
✗
No sorted order (use a BST/map for that).
Advantages & Disadvantages
Advantages
O(1) average insert, search, delete.
Turns nested-loop O(n²) into single-pass O(n).
Flexible keys (strings, tuples with custom hashers).
Foundation of sets, maps, caches, dedup.
Disadvantages
No ordering — can't do range queries or sorted iteration.
// Two Sum — O(n) with a hash map
vector<int> twoSum(vector<int>& a, int target){
unordered_map<int,int> seen; // value → indexfor (int i = 0; i < a.size(); i++) {
int need = target - a[i];
if (seen.count(need)) return {seen[need], i};
seen[a[i]] = i;
}
return {};
}
// Chaining hash set (illustrative)structHashSet {
static const int B = 769; // prime capacity
vector<int> bucket[B];
intidx(int k){ return (k % B + B) % B; }
voidadd(int k){ auto& c = bucket[idx(k)];
if (find(c.begin(),c.end(),k)==c.end()) c.push_back(k); }
boolhas(int k){ auto& c = bucket[idx(k)];
return find(c.begin(),c.end(),k)!=c.end(); }
};
Interactive Hash Table Visualization
Interactive Hash Table Visualization
BucketTarget bucketEntryCollisionFound
Idle
Current operation details
Operation
—
hash(key) % ${'cap'}
—
Load factor α
0.00
Steps
0
taken
Entries
0
stored
Collisions
0
so far
Buckets
7
capacity
Step — of —
Select a scenario above, or use the manual controls, then press Play. hash(k) = k mod capacity.
Manual controls — integer keys, capacity is a small prime
✓ Done
Speed
Step-by-step operation log
Step
Key
Bucket
Action
Collisions
Run a scenario to populate the log.
Key Patterns
Hash map = O(1) lookup. The universal speedup: replace "search the array again" (O(n) inner loop) with a hash map lookup (O(1)). Two Sum, subarray-sum-equals-k, longest consecutive sequence, group anagrams all use this.
Frequency counting.map[x]++ in one pass gives you counts for anagrams, majority element, top-K, and first-unique problems. For a small fixed alphabet, an int[26]/int[128] array is even faster.