LeetCode 49 / Classic Grouping · Hash Map Medium

Group Anagrams

LC
Practice this algorithm on LeetCode to reinforce your understanding.
Open Problem

Anagrams share the same sorted letters, so a sorted-string key buckets them together in one pass — O(N·K log K) time

What does it solve?

Group a list of words so that anagrams land together: ["eat","tea","tan","ate","nat","bat"] → [["eat","tea","ate"],["tan","nat"],["bat"]]. The trick is finding a canonical key that's identical for all anagrams.

Key insight: two words are anagrams exactly when their sorted letters match. So sort each word to get a canonical key, then use a hash map from key → list of original words. Every word drops into its bucket in O(1) after an O(K log K) sort. This "group by canonical key" is the core grouping pattern.

The core idea

groups = {}
for word in words:
  key = sorted(word) # canonical form
  groups[key].append(word)
return groups.values()

Complexity

Time complexity
O(N·K log K)

N words, each of length up to K. Sorting each word is O(K log K); map insert is O(K) to hash the key.

Space complexity
O(N·K)

The map stores every word plus its key. An O(K) counting-key variant avoids the log factor.


Examples & edge cases

Live animation — sort each word into its bucket
current word sorted key new bucket existing bucket
Input words
Press Play to begin…
Hash map — sorted key → group of words
{ } empty
Current step detail
word = — key = — buckets = — groups = —
Step — of —
current word
—
being placed
sorted key
—
canonical form
buckets
—
distinct keys
words placed
—
of total
Select an example and press Play to start.
✓ Done
SpeedMedium

Step-by-step table

Stepwordsorted keybucketactiongroups

C++ implementation

group_anagrams.cpp
#include <bits/stdc++.h>
using namespace std;

// Group words that are anagrams of each other (LeetCode 49)
vector<vector<string>> groupAnagrams(vector<string>& words) {
    unordered_map<string, vector<string>> groups;

    for (string& w : words) {
        string key = w;
        sort(key.begin(), key.end());   // canonical key: sorted letters
        groups[key].push_back(w);        // drop into its bucket
    }

    vector<vector<string>> res;
    for (auto& [key, grp] : groups) res.push_back(grp);
    return res;
}

int main() {
    vector<string> w = {"eat","tea","tan","ate","nat","bat"};
    for (auto& g : groupAnagrams(w)) {
        for (auto& s : g) cout << s << " ";
        cout << "\n";
    }
    return 0;
}

My Notes

📝Notes✅

▼

Practice this problem