Skip to main content

Group Anagrams

How to notice that the real point is not the map itself, but choosing a canonical key that represents the group.

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

Common mistakes

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 -> aet
  • tea -> aet
  • ate -> 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 []
}
solution.ts
Stuck? Hints available.

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 Map is 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.

Next challenge Product of Array Except Self Previous challenge Container With Most Water

Related challenges

Related articles