Sets & Maps
Sets answer “have I seen this key?” Maps answer “what information belongs to this key?” Hash-based lookup, insertion, and deletion take expected time.
1. Reusable Idea: Frequency Maps
A frequency map stores value -> number of occurrences:
counts = {}
for value in values:
counts[value] = counts.get(value, 0) + 1
Build it in time and space, where is the number of unique values. Use it for counting, duplicate detection, most-frequent values, anagrams, and multiset comparison.
A second pass over at most entries is still overall, so prefer the clearest solution over forcing everything into one loop.
2. Use the Input Range
Space depends on the number of possible unique keys, not the number of insertions. If a problem counts first IPv4 octets, there are only 256 possible values, so a 256-element count array uses space.
| Key range | Good representation | Extra space |
|---|---|---|
| Lowercase letters | 26-element count array | |
| Byte or IPv4 octet | 256-element count array | |
| Large or sparse values | Frequency map |
Use a fixed array when the range is small and dense; use a map when it is large, sparse, or not numeric.
3. Common Bugs and Misconceptions
- Assuming iteration order: sort explicitly when the output requires order.
- Mutating while iterating: collect changes first, then apply them in a second pass.
- Using mutable keys: use an immutable tuple or
frozenset, and never modify an object while it is a key. - Confusing missing with zero: check membership or use a safe default.
- Losing duplicate counts: a set stores presence only; use a frequency map when multiplicity matters.
- Using hashing for nearest values: hash tables support exact lookup, not predecessor, successor, or range search. Use sorting plus binary search or a tree-based map.
4. Reusable Idea: Impose a Canonical Order
When order is irrelevant, normalize equivalent inputs before comparing or hashing them:
["b", "a", "c"] -> ("a", "b", "c")
["c", "b", "a"] -> ("a", "b", "c")
Use tuple(sorted(items)) when duplicates matter, or frozenset(items) when they do not. Sorting items costs , so include that work in the complexity.
5. Applications and Related Problems
Choose the smallest structure that answers the question:
| Question | Structure |
|---|---|
| “Have I seen this?” | Set |
| “Where did I see this?” | Map from value to index |
| “What belongs to this group?” | Map from key to set or list |
| “Are these unordered collections equal?” | Set of canonical keys |
Before coding, write one concrete entry such as IP -> set of domains or value -> original index. This prevents choosing the right outer structure but the wrong value type.
Match an Earlier Complement
In Two Sum, store value -> earlier index. For each value, look up target-value before recording the current index, so one position cannot match itself. [3,3] with target 6 must still work: the second occurrence finds the first. Expected time is and space .
Hash operations are expected constant-time only for bounded-size keys and ordinary collision behavior. Building or hashing a length-k string or tuple can cost ; include that cost when canonicalizing groups. A hash match alone is not proof of equality if you store only a lossy fingerprint instead of the full key.
6. Key Takeaways
- Trade memory for expected exact lookups and fewer repeated scans.
- Reach for a frequency map when the problem says count, duplicate, most frequent, or anagram.
- Exploit a small input range with a fixed-size array.
- Normalize order-insensitive data into one immutable canonical key.
- State exactly what each key and value means, and keep keys stable.
Continue to Sliding Windows for counts that change as a range moves, and Prefix Sums for maps from running totals to counts or indices.
Practice Problems
Core Practice
Two Sum
Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.
Most Shared Account
Count connections per username, then return the username with the largest count.
Multi-Account Cheating
Canonicalize each unordered IP list, then detect duplicate signatures.
Optional Variations (3)
Choose a variation when you want to explore a specific pattern. These are not required before moving to the next topic.
Contains Duplicate
Given an integer array nums, return true if any value appears at least twice, and false if every element is distinct.
Valid Anagram
Given two strings s and t, return true if t is an anagram of s, and false otherwise.
Most Frequent Octet
Exploit the 0–255 input range with a fixed-size frequency array.