Group Anagrams Using Hash Map in DSA C# - 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 work increase when we have more words or longer words?
Analyze the time complexity of the following code snippet.
public IList> GroupAnagrams(string[] strs) {
var map = new Dictionary>();
foreach (var s in strs) {
var chars = s.ToCharArray();
Array.Sort(chars);
var key = new string(chars);
if (!map.ContainsKey(key)) {
map[key] = new List();
}
map[key].Add(s);
}
return new List>(map.Values);
}
This code groups words that are anagrams by sorting each word and using the sorted word as a key in a hash map.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Looping through each word and sorting its characters.
- How many times: Once for each word in the input array.
For each word, sorting its characters takes time proportional to the word's length times log of that length.
| Input Size (n = number of words) | Approx. Operations |
|---|---|
| 10 (words of length k) | About 10 x k log k operations |
| 100 | About 100 x k log k operations |
| 1000 | About 1000 x k log k operations |
Pattern observation: The total work grows linearly with the number of words, and sorting each word adds a small extra cost depending on word length.
Time Complexity: O(n x k log k)
This means the time grows roughly in proportion to the number of words times the cost to sort each word.
[X] Wrong: "Sorting each word is constant time, so overall time is just O(n)."
[OK] Correct: Sorting depends on word length, so it adds a factor of k log k, which can be significant if words are long.
Understanding this time complexity helps you explain how your solution scales and why sorting each word is necessary to group anagrams efficiently.
"What if we used character count arrays instead of sorting each word? 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 anagrams.Final Answer:
Use sorted strings as keys to group words with the same letters -> Option AQuick Check:
Sorted string key groups anagrams [OK]
- Using word length as key causes wrong grouping
- Using first or last letter misses many anagrams
- Not sorting letters before using as key
Solution
Step 1: Identify correct dictionary type
We need keys as strings (sorted words) and values as lists of strings (anagrams).Step 2: Check each option
var map = new Dictionary(); uses Dictionary which fits the requirement.Final Answer:
var map = new Dictionary(); -> Option AQuick Check:
Dictionary with string keys and list values [OK]
- Using List of dictionaries instead of dictionary
- Using wrong key or value types
- Using Dictionary which can't group anagrams
var strs = new string[] {"eat", "tea", "tan", "ate", "nat", "bat"};
var map = new Dictionary();
foreach (var s in strs) {
var key = String.Concat(s.OrderBy(c => c));
if (!map.ContainsKey(key)) map[key] = new List<string>();
map[key].Add(s);
}
foreach (var group in map.Values) {
Console.WriteLine(string.Join(", ", group));
}Solution
Step 1: Sort each word to find keys
"eat", "tea", "ate" all sort to "aet"; "tan", "nat" to "ant"; "bat" to "abt".Step 2: Group words by keys and print
Groups are ["eat", "tea", "ate"], ["tan", "nat"], ["bat"]. Printed line by line.Final Answer:
"eat, tea, ate\ntan, nat\nbat" -> Option CQuick Check:
Sorted keys group anagrams correctly [OK]
- Printing all words in one line
- Grouping by unsorted words
- Mixing groups incorrectly
var map = new Dictionary();
foreach (var s in strs) {
var key = s.OrderBy(c => c).ToString();
if (!map.ContainsKey(key)) map[key] = new List<string>();
map[key].Add(s);
}Solution
Step 1: Understand s.OrderBy(c => c)
This returns IEnumerable<char>, not a string.Step 2: Using ToString() on IEnumerable<char>
ToString() returns type name, not sorted string key. Need to join chars to string.Final Answer:
Using ToString() on IEnumerable<char> does not produce sorted string key -> Option DQuick Check:
Use String.Concat or new string() to convert chars to string [OK]
- Calling ToString() on IEnumerable<char> expecting string
- Not initializing dictionary before use
- Ignoring key existence check
Solution
Step 1: Normalize case for grouping
Convert each string to lowercase to treat "Eat" and "tea" the same.Step 2: Sort the lowercase string and use as key
Sorting lowercase letters groups anagrams ignoring case.Final Answer:
Convert each string to lowercase before sorting and using as key -> Option BQuick Check:
Lowercase + sort = case-insensitive grouping [OK]
- Sorting without case normalization
- Using original case keys causing separate groups
- Grouping by length which is insufficient
Ready to prove it?
Pass the test and this pattern moves unknown
