March 24
Group Anagrams
How to notice that the real point is not the map itself, but choosing a canonical key that represents the group.
Hash Map Intermediate 18 min TypeScript
Given an array of strings strs, group the anagrams together. You can return the answer in any order.
Example:
Input: strs = ["eat","tea","tan","ate","nat","bat"]
Output: [["bat"],["nat","tan"],["ate","eat","tea"]]
What to notice before coding
- The problem does not ask you to compare every word pair manually.
- The real challenge is deciding which key represents an anagram group.
- If the key is wrong, the hash map will not save the solution.
Common mistakes
- using the original string as the key and splitting anagrams apart
- thinking the hash map is the full answer instead of the grouping structure
Step 1 — Stop focusing on the original order
eat and tea do not look equal on the surface.
But they belong to the same group.
That means the grouping key cannot depend on original order.
Step 2 — Write a correct baseline
One possible baseline is to, for each word, search whether it fits an existing group:
export function groupAnagrams(strs: string[]): string[][] {
const groups: string[][] = []
for (const word of strs) {
const normalizedWord = word.split('').sort().join('')
let placed = false
for (const group of groups) {
const normalizedGroup = group[0].split('').sort().join('')
if (normalizedGroup === normalizedWord) {
group.push(word)
placed = true
break
}
}
if (!placed) {
groups.push([word])
}
}
return groups
}
It works. But you keep searching group by group.
Step 3 — Ask what the canonical key should be
A Hash Map only helps if equivalent words generate the same key.
A simple key here is:
- sort the word's characters
So:
eat->aettea->aetate->aet
The Hash Map only starts helping after that decision is correct.
Step 4 — Group by derived key
Now the problem becomes:
- compute the key
- fetch the group for that key
- append the word
The strongest part of the solution is the key, not the Map by itself.
The interactive editor needs JavaScript. You can still read the prompt and copy the starter code below.
Starter code
export function groupAnagrams(strs: string[]): string[][] {
// your solution here
return []
}
Haven't solved it yet?
Viewing the solution now may reduce learning. It's worth trying a bit more.
Open the reference solution
Without JavaScript, the reference solution is shown inline instead of in a dialog.
Solution
Final complexity
Time: O(n * k log k)
Space: O(n * k)
Solution 1 — Search group by group
Correct, but with repeated work.
export function groupAnagrams(strs: string[]): string[][] {
const groups: string[][] = []
for (const word of strs) {
const normalizedWord = word.split('').sort().join('')
let placed = false
for (const group of groups) {
const normalizedGroup = group[0].split('').sort().join('')
if (normalizedGroup === normalizedWord) {
group.push(word)
placed = true
break
}
}
if (!placed) {
groups.push([word])
}
}
return groups.map((group) => [...group].sort()).sort((a, b) => a[0].localeCompare(b[0]))
}
Solution 2 — Hash Map with canonical key
Now each word finds its group by direct lookup.
export function groupAnagrams(strs: string[]): string[][] {
const groups = new Map<string, string[]>()
for (const word of strs) {
const key = word.split('').sort().join('')
const group = groups.get(key) ?? []
group.push(word)
groups.set(key, group)
}
return [...groups.values()]
}
If you want an optimization discussion in interviews, you can mention letter-frequency signatures as an alternative key.
The idea stays the same: derive one canonical representation first, then store it in a Hash Map.
What to say in the interview
A strong short explanation would be:
The main point here is finding a canonical representation for every anagram in the same group. I use the sorted word as the key. After that, the
Hash Mapis just the grouping mechanism: same key, same bucket.
That shows that you:
- understood that key design comes before the structure
- explained the grouping clearly
- treated the map as a tool, not magic
When this pattern shows up again
The same pattern comes back when you need to:
- group equivalent items
- derive a comparison key
- deduplicate by canonical representation
- separate normalization from storage
The point is not memorizing
groupAnagrams.
The point is learning how to choose a key that represents what the problem considers equal.