Hashing — Hash Maps & Hash Sets
Hash Maps & Hash Sets · Collision Handling · Frequency Counting · Grouping — the single most powerful technique for reducing O(n²) solutions to O(n).
Section 1 — What Is Hashing?
Hashing is the process of converting a key of any type into a fixed-size integer (the hash code) and using that integer as an index into an array (the hash table). This gives us O(1) average-case insertion, deletion, and lookup — regardless of how many elements are stored.
1.1 — Hash Function & Collision Handling
A hash function maps keys to indices. Two keys can hash to the same index — a collision. C++ resolves collisions via chaining (linked list at each index) in unordered_map.
- Chaining: Each bucket holds a linked list. Average O(1); worst case O(n) if all keys collide.
- Load factor: When table is ≥ 75% full, it rehashes to a larger table. O(n) but amortized O(1).
- In C++:
unordered_mapuses open addressing withstd::hashinternally.
1.2 — C++ API
// unordered_set — existence only
unordered_set
// Default int value in map is 0 unordered_map<int,int> cnt; cnt[key]++; // OK — default-initialises to 0 then increments
</div>
<div class="ch-cplx-row">
<span class="ch-cplx"><span>All ops average</span>O(1)</span>
<span class="ch-cplx"><span>Space</span>O(n)</span>
<span class="ch-cplx"><span>Worst case</span>O(n)</span>
</div>
</div>
<div class="chapter-section">
<h2 class="section-heading">Section 2 — Pattern: Existence Check</h2>
<p>Use <code>unordered_set</code> when you just want to know if a value has been seen. O(1) average per lookup.</p>
<div class="ch-code-wrap">
```cpp
// Pangram check — has the sentence all 26 letters?
unordered_set<char> letters(sentence.begin(), sentence.end());
return letters.size() == 26;
// Has any duplicate?
unordered_set<int> seen;
for (int x : nums) {
if (seen.count(x)) return true; // duplicate found
seen.insert(x);
}
return false;
Section 3 — Pattern: Frequency Count
Use unordered_map<T, int> to count how many times each element appears. Foundation for anagram, top-K, most-frequent problems.
// Is Anagram — same char frequencies? unordered_map<char,int> cnt; for (char c : s) cnt[c]++; for (char c : t) { if (—cnt[c] < 0) return false; } return true;
// Top K frequent elements — combine freq map + heap unordered_map<int,int> freq; for (int x : nums) freq[x]++; priority_queue<pair<int,int>, vector<pair<int,int>>, // min-heap by frequency greater<pair<int,int>>> pq; for (auto& [val, cnt] : freq) { pq.push({cnt, val}); if (pq.size() > k) pq.pop(); }
</div>
</div>
<div class="chapter-section">
<h2 class="section-heading">Section 4 — Pattern: Two-Sum Lookup</h2>
<p>For each element x, check if its complement (target - x) exists in the hash map. One-pass O(n).</p>
<div class="insight-box">
<span class="insight-label">General Two-Sum Pattern</span>
Store what you have seen so far. For each new element, ask: "Is its complement already here?" This converts O(n²) nested search into O(n) with one hash table lookup.
</div>
<div class="ch-code-wrap">
```cpp
// Classical two-sum — return indices
unordered_map<int,int> seen; // val → index
for (int i = 0; i < nums.size(); i++) {
if (seen.count(target - nums[i]))
return {seen[target-nums[i]], i};
seen[nums[i]] = i;
}
// Counting elements (x+1 exists for all x in set)
unordered_set<int> s(arr.begin(), arr.end());
int count = 0;
for (int x : arr) if (s.count(x+1)) count++;
return count;
Section 5 — Pattern: Grouping
Map a grouping key to a list of all elements sharing that key. Classic example: group anagrams by their sorted form.
Section 6 — Pattern: Sliding Window + HashMap
Maintain a frequency map of elements in the current window. Expand right, shrink left when constraint violated.
Section 7 — Pattern: Prefix Sum + HashMap
Store cumulative prefix sums and their frequencies. For each prefix sum curr, the count of subarrays summing to target ending at this index = freq[curr - target].
Practice Problems
| # | Problem | Pattern | Diff |
|---|---|---|---|
| 1 | 1832. Check if the Sentence Is Pangram | Existence check (set) | Easy |
| 2 | 268. Missing Number | Existence check (set) | Easy |
| 3 | 1426. Counting Elements | Two-sum lookup (x+1) | Easy |
| 4 | 1. Two Sum | Two-sum lookup | Easy |
| 5 | 383. Ransom Note | Frequency count | Easy |
| 6 | 771. Jewels and Stones | Existence check (set) | Easy |
| 7 | 2225. Find Players With Zero or One Losses | Frequency count (map) | Medium |
| 8 | 1133. Largest Unique Number | Frequency count (unique = 1) | Easy |
| 9 | 1189. Maximum Number of Balloons | Frequency ratio | Easy |
| 10 | 49. Group Anagrams | Grouping (sorted key) | Medium |
| 11 | 347. Top K Frequent Elements | Frequency count + heap | Medium |
| 12 | 560. Subarray Sum Equals K | Prefix sum + HashMap | Medium |
| 13 | 146. LRU Cache | HashMap + Doubly Linked List | Medium |