Foundations
Hash Map & Set (JS Map and Set)
Fundamentals · Starter
Level: StarterHash Map / Set Lookup
Complexity
| Operation | Map | Set | Time |
|---|---|---|---|
| Add or update | set(k, v) | add(v) | O(1) average |
| Lookup | get(k) | has(v) | O(1) average |
| Remove | delete(k) | delete(v) | O(1) average |
| Size | size | size | O(1) |
| Iterate | for...of | for...of | O(n) |
Space is O(n).
A hash map stores key-value pairs and finds a value from its key in O(1) on average. A set stores unique values and answers "is this in here?" in O(1). In JavaScript these are Map and Set. The theory (hash functions, collisions) is in the Hash Table topic.
Map or plain object
Map | Object | |
|---|---|---|
| Key types | Anything | Strings and symbols |
| Order | Insertion order, always | Mostly, but integer-like keys come first |
| Size | map.size | Object.keys(o).length |
| Inherited keys | None | 'toString' in {} is true |
| Best for | Frequency counts, caches, lookups | Fixed records of known fields |
Key equality
Map and Set compare keys with SameValueZero. Primitives compare by value, objects and arrays compare by reference.
new Set([[1, 2], [1, 2]]).size; // 2, two different arrays
new Set([NaN, NaN]).size; // 1, NaN equals NaN hereTo key by a pair, build a string key: `${r},${c}`.
Patterns it unlocks
- Frequency count:
map.set(x, (map.get(x) ?? 0) + 1). - Seen set: detect duplicates or visited nodes in one pass.
- Complement lookup: Two Sum.
- Group by key: anagrams (sorted word as key), buckets.
- Cache: memoization, LRU (a Map keeps insertion order).
- Index: value to position for O(1) jumps.
Common mistakes
- Using an array
includesin a loop when a Set would make it O(n) instead of O(n²). - Using an object as a map with user-supplied keys such as
__proto__. - Expecting two equal-looking arrays to be the same key.
- Mutating a Map or Set while iterating over it.
Code
export const frequencies = items => {
const freq = new Map();
for (const x of items) freq.set(x, (freq.get(x) ?? 0) + 1);
return freq;
};
export const hasDuplicate = nums => new Set(nums).size !== nums.length;
export const twoSum = (nums, target) => {
const index = new Map(); // value -> position
for (let i = 0; i < nums.length; i++) {
if (index.has(target - nums[i])) return [index.get(target - nums[i]), i];
index.set(nums[i], i);
}
return null;
};
export const groupAnagrams = words => {
const groups = new Map();
for (const w of words) {
const key = [...w].sort().join('');
groups.set(key, [...(groups.get(key) ?? []), w]);
}
return [...groups.values()];
};
export const intersection = (a, b) => {
const inA = new Set(a);
return [...new Set(b.filter(x => inA.has(x)))];
};Practice
Hash Map / Set Lookup
- Two SumEasy
- Contains DuplicateEasy
- Valid AnagramEasy
- Ransom NoteEasy
- Isomorphic StringsEasy
- Intersection of Two ArraysEasy
- Majority ElementEasy
- Single NumberEasy
- Group AnagramsMedium
- Longest Consecutive SequenceMedium
- LRU CacheMedium
- Insert Delete GetRandom O(1)Medium
- Encode and Decode TinyURLMedium
- 4Sum IIMedium
- Brick WallMedium
- Custom Sort StringMedium
- LFU CacheHard
- All O`one Data StructureHard
Spotted a mistake or something unclear? Report it on GitHub.