Group Anagrams Using Hash Map in DSA C++ - Time & Space Complexity
We want to know how the time needed to group anagrams grows as we get more words.
How does the program's speed change when the list of words gets bigger?
Analyze the time complexity of the following code snippet.
#include <vector>
#include <string>
#include <unordered_map>
#include <algorithm>
std::vector<std::vector<std::string>> groupAnagrams(std::vector<std::string>& strs) {
std::unordered_map<std::string, std::vector<std::string>> map;
for (auto &s : strs) {
std::string key = s;
std::sort(key.begin(), key.end());
map[key].push_back(s);
}
std::vector<std::vector<std::string>> result;
for (auto &pair : map) {
result.push_back(pair.second);
}
return result;
}
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: Loop over all words and sort each word.
- How many times: Once for each word in the input list.
As the number of words grows, the program sorts each word and inserts it into the map.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | Sort 10 words, each of length k, plus 10 insertions |
| 100 | Sort 100 words, each of length k, plus 100 insertions |
| 1000 | Sort 1000 words, each of length k, plus 1000 insertions |
Pattern observation: The time grows roughly in proportion to the number of words times the length of each word.
Time Complexity: O(n * k log k)
This means the time grows with 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 takes more time for longer words, affecting total time.
Understanding how sorting inside loops affects time helps you explain and improve solutions confidently.
"What if we used character counts instead of sorting each word? How would the time complexity change?"
Practice
Solution
Step 1: Understand anagram grouping
Anagrams have the same characters in different orders, so sorting the string gives a unique key for all anagrams.Step 2: Use sorted string as hash map key
By sorting each word and using it as a key, all anagrams map to the same key and can be grouped together.Final Answer:
Use sorted strings as keys to group words with the same characters -> Option AQuick Check:
Sorted string key = group anagrams [OK]
- Using string length as key misses different anagrams
- Using first or last character groups unrelated words
- Not sorting strings before using as keys
Solution
Step 1: Identify key and value types
The key should be a string (sorted word), and the value should be a vector of strings (group of anagrams).Step 2: Match correct declaration
std::unordered_map> anagramGroups; uses unordered_map with key as string and value as vector<string>, which is correct for grouping anagrams.Final Answer:
std::unordered_map> anagramGroups; -> Option CQuick Check:
Key=string, Value=vector<string> [OK]
- Using int as key instead of string
- Using vector<char> as key (not hashable)
- Using string as value instead of vector<string>
std::vector words = {"eat", "tea", "tan", "ate", "nat", "bat"};
std::unordered_map> groups;
for (auto &word : words) {
std::string sortedWord = word;
std::sort(sortedWord.begin(), sortedWord.end());
groups[sortedWord].push_back(word);
}
for (auto &pair : groups) {
std::cout << "Group: ";
for (auto &w : pair.second) std::cout << w << " ";
std::cout << std::endl;
}Solution
Step 1: Sort each word and group by sorted key
"eat", "tea", "ate" all sort to "aet" so grouped together; "tan", "nat" sort to "ant"; "bat" sorts to "abt".Step 2: Print groups
Groups printed are: "eat tea ate", "tan nat", and "bat".Final Answer:
Group: eat tea ate Group: tan nat Group: bat -> Option BQuick Check:
Sorted keys group anagrams correctly [OK]
- Not sorting words before grouping
- Mixing groups by original word order
- Printing keys instead of grouped words
std::vector words = {"abc", "bca", "cab"};
std::unordered_map> groups;
for (auto word : words) {
std::string key = word;
std::sort(word.begin(), word.end());
groups[key].push_back(word);
}Solution
Step 1: Analyze sorting and key usage
The code sorts 'word' but uses 'key' (unsorted) as the map key, so grouping is incorrect.Step 2: Correct usage
Sort 'key' and use it as the map key to group anagrams properly.Final Answer:
Sorting is done on 'word' but 'key' is used as map key, causing wrong grouping -> Option AQuick Check:
Sort key before using in map [OK]
- Sorting wrong variable before using as key
- Using unsorted string as map key
- Ignoring reference vs copy in loop
Solution
Step 1: Normalize case for consistent keys
Convert each string to lowercase so that case differences do not affect grouping.Step 2: Sort the lowercase string and use as key
Sorting the lowercase string ensures all case variants of anagrams map to the same key.Step 3: Group anagrams using normalized keys
Use the lowercase sorted string as the hash map key to group anagrams case-insensitively.Final Answer:
Convert each string to lowercase before sorting and using as key -> Option DQuick Check:
Lowercase + sort = case-insensitive grouping [OK]
- Not normalizing case before grouping
- Using original case strings as keys
- Grouping by length or unsorted strings
Ready to prove it?
Pass the test and this pattern moves unknown
