learn deep. ship safe.Practice testsFollow ByteMunSubscribe

mediumStringsHash mapSorting

Group Anagrams

Group words that are anagrams of each other. Tests whether you can design a good hash key and keep the output in a well-defined order.

By Tests checked by DeepakJavaScript or Python

Given a list of lowercase words, group together the words that are anagrams of each other (the same letters in a different order).

Return the groups in the order their first word appears in the input. Inside each group, keep the words in input order.

Examples

Example 1

Input: words = ["eat", "tea", "tan", "ate", "nat", "bat"]
Output: [["eat", "tea", "ate"], ["tan", "nat"], ["bat"]]

Example 2

Input: words = [""]
Output: [[""]]
Why: An empty string is its own group

Constraints

  • 1 <= words.length <= 10^4
  • 0 <= words[i].length <= 100
  • Words contain only lowercase letters

Hints

Hint 1

Two words are anagrams exactly when they look the same after sorting their letters.

Hint 2

Use the sorted word as a map key. Most languages' maps keep insertion order, which gives you the required group order for free.

Solution

Show the solution (try it yourself first)

Approach: a canonical key in a hash map

Anagrams contain exactly the same letters, so sorting each word gives the same string for every word in a group: "eat", "tea" and "ate" all become "aet". Use that sorted string as a map key and append each word to its group. JavaScript's Map and Python's dict keep insertion order, so groups come out in the order their first word appeared, as required. Sorting costs O(k log k) per word; for long words, a 26-letter count array joined into a string is a faster key.

function groupAnagrams(words) {
  const groups = new Map();
  for (const w of words) {
    const key = [...w].sort().join('');
    if (!groups.has(key)) groups.set(key, []);
    groups.get(key).push(w);
  }
  return [...groups.values()];
}

Complexity

Time O(n · k log k) for n words of length up to k. Space O(n · k) for the groups.

Case 1Input: ["eat","tea","tan","ate","nat","bat"]Expected: [["eat","tea","ate"],["tan","nat"],["bat"]]
Case 2Input: [""]Expected: [[""]]

Run checks these 2 samples. Submit checks all 7 tests, including hidden ones.

  1. Longest Substring Without RepeatsStrings · Sliding window · Hash map
    medium
  2. Merge Overlapping IntervalsArrays · Sorting · Intervals
    medium
  3. Pair with Target SumArrays · Hash map
    easy
  4. Balanced BracketsStack · Strings
    easy