Group Anagrams
Problem (restated)
Given an array of strings, group the anagrams together. Order of groups and order inside a group can be anything.
Intuition
Anagrams share a signature: sorted characters, or a 26-count tuple. Hash map signature → list of words.
Approaches
Hash map with sorted key
Tested onlyIdea. For each word, key = sorted(word). Append word to map[key].
Walkthrough. [“eat”,“tea”,“tan”,“ate”] → keys “aet” groups eat/tea/ate; “ant” groups tan.
Trade-offs. Simple. Count-array key is O(n·k) and faster when k is large.
export function groupAnagrams(strs: string[]): string[][] {
const map = new Map<string, string[]>();
for (const s of strs) {
const key = [...s].sort().join("");
const bucket = map.get(key) ?? [];
bucket.push(s);
map.set(key, bucket);
}
return [...map.values()];
}
export function groupAnagrams(strs: string[]): string[][] {
const map = new Map<string, string[]>();
for (const s of strs) {
const key = [...s].sort().join("");
const bucket = map.get(key) ?? [];
bucket.push(s);
map.set(key, bucket);
}
return [...map.values()];
}
Hash map with count signature
Tested onlyIdea. Key from 26 letter counts joined as a string (or tuple).
Walkthrough. Same grouping, linear in total characters.
Trade-offs. Better asymptotics for long strings; slightly more code.
export function groupAnagramsCount(strs: string[]): string[][] {
const map = new Map<string, string[]>();
for (const s of strs) {
const cnt = new Array(26).fill(0);
for (const ch of s) cnt[ch.charCodeAt(0) - 97]++;
const key = cnt.join("#");
const bucket = map.get(key) ?? [];
bucket.push(s);
map.set(key, bucket);
}
return [...map.values()];
}
export function groupAnagramsCount(strs: string[]): string[][] {
const map = new Map<string, string[]>();
for (const s of strs) {
const cnt = new Array(26).fill(0);
for (const ch of s) cnt[ch.charCodeAt(0) - 97]++;
const key = cnt.join("#");
const bucket = map.get(key) ?? [];
bucket.push(s);
map.set(key, bucket);
}
return [...map.values()];
}
Template connection
groupByKey from the Hashing template. key is the anagram signature.
Reflection
- Which pattern gave this away within 90 seconds?
- What changed from the standard template?
- What would break the current solution?