Frequency Counter¶
Also known as: Hash Map Counting, Dictionary Lookup, Hash Set
The moment you catch yourself about to write a loop inside a loop — comparing every item against every other item — stop. A frequency counter does the same job in a single pass by remembering what you've already seen. You spend a little memory to buy a lot of speed.
Before you start¶
- Comfortable writing a basic loop, and using a hash map / dictionary in your language: storing a key, looking one up, checking whether one exists.
What 'solved properly' looks like
Target: O(n) time, O(n) space. If your solution is slower than that, you've found a solution but not this pattern — the judge says "Accepted" either way, so treat this as your real benchmark.
The idea¶
You make one pass over the data and record what you see in a hash map (or a set) — counts, last-seen positions, or just "yes, this existed." Because a hash map looks things up in roughly constant time, a question that would otherwise force you to re-scan the data for every element ("has this appeared before?", "how many times?", "is its partner here?") collapses into a single cheap lookup.
Why it matters: It's the simplest optimization pattern, and it's the one hiding inside dozens of harder ones — two-sum lookups, sliding-window character counts, grouping, de-duplication. Making it automatic now lightens everything later, because you stop reaching for nested loops by reflex.
When to reach for it¶
Reach for it when a problem is about duplicates, counting how often things occur, finding a pair that satisfies a condition, checking whether two things are anagrams, finding the "first unique" element, or computing an intersection. Words like "unique", "count", "frequency", "have we seen", or "appears more than once" are a strong tell — especially when the obvious solution would compare everything to everything.
When not to use it
If the array is already sorted and you only need to find a pair, you usually don't need a hash map at all — two pointers does it in O(1) extra space. The frequency counter earns its memory when the data is unsorted or you genuinely need counts; don't spend the space when the ordering is already doing the work for you. Also remember that a hash map throws away order: if the problem needs original positions, store the index, not just a tally.
Practice set¶
Work these top to bottom. The time-box is a cue to pause and re-read the triggers above if you're still stuck when it passes — not a deadline to race. Getting unstuck by stepping back is the skill being trained.
| # | Problem | Where | Difficulty | Time-box | Role |
|---|---|---|---|---|---|
| 1 | Contains Duplicate | LeetCode | Easy | 15 mins | teaching |
| 2 | Valid Anagram | LeetCode | Easy | 20 mins | teaching |
| 3 | Two Sum | LeetCode | Easy | 20 mins | consolidation |
| 4 | First Unique Character in a String | LeetCode | Easy | 20 mins | consolidation |
| 5 | Group Anagrams | LeetCode | Medium | 30 mins | challenge |
Already know this? Test out.
If you can solve Group Anagrams cleanly in one sitting without help — picking a sensible key for the map and explaining why it works — you already own this pattern, so move on to the next one. If it tangles you up, that's your signal to work the set from the top instead of skipping.