Given an array of strings, group the anagrams together — every string in a group is a rearrangement of the same characters. The machine must assign each string to a bucket such that two strings land in the same bucket exactly when their character multisets match.
The key insight: anagrams share a canonical form, so the problem reduces to computing a stable key per string. Sorting each string's characters yields one canonical key, but counting into a 26-slot frequency tuple avoids the O(k log k) sort and is collision-free for lowercase letters.
Approach:
- For each word, build a key from its character counts — a tuple of 26 frequencies.
- Use that tuple as a hash-map key; append the word to the map's bucket.
- Return the map's values as the grouped result.
def group_anagrams(strs):
buckets = {}
for word in strs:
counts = [0] * 26
for ch in word:
counts[ord(ch) - 97] += 1
key = tuple(counts)
buckets.setdefault(key, []).append(word)
return list(buckets.values())Time: O(n·k), where k is the max word length. Space: O(n·k) for the buckets.
Trickiest edge case: the empty string — its key is 26 zeros, and the tuple form keeps it distinct from single-character words, which sort-based keys also handle but frequency tuples never confuse with "".