← Learn DSA · Lesson 4 of 9
Hash Maps
Trade memory for time by remembering what you have already seen.
The idea
A hash map answers one question in constant time: have I seen this before, and what was it attached to?
That sounds modest. It is the single most common way an O(n²) solution becomes O(n).
The pattern is almost always the same shape. You are looping over data and, for each element, asking a question about the elements you have already passed. The naive version answers that by looping again — comparing every element against every other. The hash-map version answers it by having written those elements down as it went.
for each element:
if the map already answers my question -> done
otherwise, record this element and move onThe cost is memory: you are storing up to n entries to avoid the second loop. That trade is the whole idea, and it is why "time complexity" and "space complexity" are usually discussed together.
Walkthrough
One pass over the array, building a count for each value. Watch how every element is read exactly once.
What it costs
- time
- O(1) average per lookup or insert
- space
- O(n) for n stored entries
Average, not worst. A pathological set of keys that all collide degrades lookups to O(n) — rare in practice, and the reason hash functions matter.
When to reach for it
- The question is "have I seen this?" or "how many times?", asked repeatedly.
- You are about to write a nested loop whose inner half only searches for a match.
- You need to look backwards at earlier elements — a map remembers them for you.
- Keys are sparse, or are not integers at all.
Rather than the obvious alternative
Sorting first
Sorting costs O(n log n) and buys you order. If you only need counts or membership, hashing does it in O(n) and order was never the point.
A nested loop
The direct trade this structure exists for: O(n²) becomes O(n) by remembering instead of re-searching.
A tree map
Choose the tree when you need keys in sorted order, range queries, or a predecessor. A hash map gives you none of those, and is faster when you do not need them.
How to spot it
- You are about to write a nested loop where the inner one only looks for a match.
- The question is "have I seen X?" or "how many times has X appeared?"
- You need to look *backwards* at earlier elements, never forwards.
- The naive solution is O(n²) and the problem hints that something faster exists.
Where it goes wrong
Recording before you look
If you add the current element to the map before checking for its match, an element can pair with itself. Check first, then record.
Storing the value when you need the index
Most problems want *where* something was, not what it was. Map the value to its index, not to true.
Assuming keys are unique
Duplicate values overwrite each other. If earlier occurrences matter, store a list of indices rather than one.
Try it
Two short checks. They run the same way the practice problems do — write the function, press Run.
Return true if any value appears twice in nums, otherwise false. One pass, using a set.
Tests
4 cases, 1 hidden| call | type | expected | result |
|---|---|---|---|
| hasDuplicate([1,2,3,2]) | a repeat | true | — |
| hasDuplicate([1,2,3]) | all distinct | false | — |
| hasDuplicate([]) | empty | false | — |
| withheld | hidden | withheld | — |
Hidden cases run too — their inputs aren't listed here, so aim for a general solution rather than one fitted to the cases above.
Hints
Stuck? Hints open one at a time, each giving a little more away.
2 hints left
Return an object mapping each value in nums to how many times it appears.
Tests
3 cases, 1 hidden| call | type | expected | result |
|---|---|---|---|
| countValues([1,2,2,3]) | mixed | {"1":1,"2":2,"3":1} | — |
| countValues([]) | empty | {} | — |
| withheld | hidden | withheld | — |
Hidden cases run too — their inputs aren't listed here, so aim for a general solution rather than one fitted to the cases above.
Hints
Stuck? Hints open one at a time, each giving a little more away.
2 hints left
Practise it
- Two Sumeasy
- Valid Anagrameasy
- First Unique Charactermedium
- Longest Consecutive Sequencemedium
- Group Anagramshard
Build it
The problems above are one function each. These assemble the same ideas into a working thing across several files.
- Hash MapConstruct a high-performance hash map with bucket arrays, modular hashing, collision chaining, and dynamic rehashing.4 stepsjavascript · pythonmedium
- LRU CacheBuild a fixed-size cache that throws away whatever was used least recently.4 stepsjavascript · pythonmedium
- Rate Limiter (Token Bucket)Bound a client to a sustained rate while still tolerating a burst.4 stepsjavascript · pythonmedium