Group Anagrams Using Hash Map in DSA Go - Time & Space Complexity
We want to understand how the time needed to group anagrams grows as the list of words gets bigger.
Specifically, how does the code handle many words and their letters efficiently?
Analyze the time complexity of the following code snippet.
func groupAnagrams(strs []string) [][]string {
m := make(map[string][]string)
for _, s := range strs {
chars := []rune(s)
sort.Slice(chars, func(i, j int) bool { return chars[i] < chars[j] })
key := string(chars)
m[key] = append(m[key], s)
}
result := [][]string{}
for _, v := range m {
result = append(result, v)
}
return result
}
This code groups words that are anagrams by sorting each word's letters and using the sorted word as a key in a map.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Loop over all words and sorting each word's letters.
- How many times: The outer loop runs once per word (n times). Sorting runs once per word on word length (k).
As the number of words (n) grows, the code sorts each word of length (k) inside a loop.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 words, avg length 5 | 10 x 5 log 5 ≈ 10 x 11.6 = 116 |
| 100 words, avg length 5 | 100 x 5 log 5 ≈ 100 x 11.6 = 1160 |
| 1000 words, avg length 5 | 1000 x 5 log 5 ≈ 1000 x 11.6 = 11600 |
Pattern observation: The operations grow roughly linearly with the number of words, multiplied by sorting cost per word.
Time Complexity: O(n x k log k)
This means the time grows linearly with the number of words and depends on sorting each word's letters.
[X] Wrong: "The time complexity is just O(n) because we only loop once over the words."
[OK] Correct: Sorting each word takes extra time depending on word length, so the total time depends on both number of words and word length.
Understanding this complexity helps you explain how hashing and sorting combine to solve grouping problems efficiently.
"What if we used character count arrays as keys instead of sorting? How would the time complexity change?"
Practice
Solution
Step 1: Understand anagrams
Anagrams are words with the same letters in different orders.Step 2: Use sorted string as key
Sorting letters of each word gives a unique key for all its anagrams.Final Answer:
Use sorted strings as keys to group words with the same letters -> Option CQuick Check:
Sorted string key = group anagrams [OK]
- Using word length as key misses different anagrams
- Using first or last letter groups unrelated words
- Not sorting letters before using as key
Solution
Step 1: Identify map key and value types
Key should be string (sorted word), value should be slice of strings (anagrams).Step 2: Check Go map initialization syntax
make(map[string][]string) creates a map with string keys and string slice values.Final Answer:
groups := make(map[string][]string) -> Option AQuick Check:
Correct map type and initialization [OK]
- Using map[string]string instead of map[string][]string
- Using slice instead of map
- Using wrong key or value types
package main
import (
"fmt"
"sort"
"strings"
)
func groupAnagrams(strs []string) map[string][]string {
groups := make(map[string][]string)
for _, word := range strs {
letters := strings.Split(word, "")
sort.Strings(letters)
key := strings.Join(letters, "")
groups[key] = append(groups[key], word)
}
return groups
}
func main() {
input := []string{"bat", "tab", "eat", "tea"}
result := groupAnagrams(input)
fmt.Println(result)
}Solution
Step 1: Sort letters of each word
"bat" and "tab" sorted to "abt"; "eat" and "tea" sorted to "aet".Step 2: Group words by sorted key
Words with key "abt" grouped as ["bat", "tab"], with key "aet" grouped as ["eat", "tea"].Final Answer:
map[abt:[bat tab] aet:[eat tea]] -> Option DQuick Check:
Sorted keys group anagrams correctly [OK]
- Not sorting letters before grouping
- Using original words as keys
- Incorrect map output format
func groupAnagrams(strs []string) map[string][]string {
groups := make(map[string][]string)
for _, word := range strs {
letters := strings.Split(word, "")
sort.Strings(letters)
key := letters[0]
groups[key] = append(groups[key], word)
}
return groups
}Solution
Step 1: Check key creation logic
Key is set as letters[0], only first letter of sorted word, not full sorted string.Step 2: Understand impact on grouping
Using only first letter groups unrelated words, failing to group anagrams correctly.Final Answer:
Using letters[0] as key instead of full sorted string -> Option BQuick Check:
Full sorted string needed as key [OK]
- Using partial key instead of full sorted string
- Forgetting to join letters into string key
- Not sorting letters before key creation
["listen", "silent", "enlist", "google", "gogole", "abc"], which Go code snippet correctly returns the grouped anagrams as a slice of slices of strings (ignoring order)?Solution
Step 1: Use sorted string as key and map to slice of strings
func groupAnagrams(strs []string) [][]string { groups := make(map[string][]string) for _, word := range strs { letters := strings.Split(word, "") sort.Strings(letters) key := strings.Join(letters, "") groups[key] = append(groups[key], word) } result := [][]string{} for _, group := range groups { result = append(result, group) } return result } correctly sorts letters, joins them as key, and appends words to groups[key].Step 2: Convert map values to slice of slices
func groupAnagrams(strs []string) [][]string { groups := make(map[string][]string) for _, word := range strs { letters := strings.Split(word, "") sort.Strings(letters) key := strings.Join(letters, "") groups[key] = append(groups[key], word) } result := [][]string{} for _, group := range groups { result = append(result, group) } return result } collects all groups into a slice of slices and returns it.Final Answer:
Option A code correctly groups anagrams and returns slice of slices -> Option AQuick Check:
Sorted key + map to slices + collect groups = correct [OK]
- Using word length as key groups wrong words
- Using map[string]string loses multiple anagrams per key
- Using original word as key misses grouping
Ready to prove it?
Pass the test and this pattern moves unknown
