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 Deepak KumarTests 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^40 <= 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.