Start learning free

LESSON 265 OF 409 · HASH TABLE

Group Anagrams II in C++ (O(n * L * log L) Time Complexity)

Practice O(n * L * log L) Read the full explanation

Given a vector of strings, group the anagrams together. You can return the answer in any order.

An anagram is a word or phrase formed by rearranging the letters of a different word or phrase, using all the original letters exactly once.

Example:

Input:   strings = ["eat","tea","tan","ate","nat","bat"]

Output:  [["bat"],["nat","tan"],["ate","eat","tea"]]

Note:

Your algorithm should run in O(n * L * log L) time and use O(n * L) extra space, where n is the number of strings and L is the length of the longest string.


STEP 1 OF 9
    Ctrl + Enter to check

    C++ · HASH TABLE

    Group Anagrams in C++, explained

    Understanding the Problem

    The core challenge of this problem is to identify and group words that are anagrams of each other. An anagram is a rearrangement of the letters of a word to form another word. For example, "eat" and "tea" are anagrams because they contain the same letters.

    This problem is significant in various applications such as text analysis, cryptography, and natural language processing where identifying similar patterns is crucial.

    Potential pitfalls include not correctly identifying all anagrams or inefficiently grouping them, leading to suboptimal performance.

    Approach

    To solve this problem, we need to group words that are anagrams. A naive solution might involve comparing each word with every other word, but this would be inefficient with a time complexity of O(n^2 * L). Instead, we can use a more optimized approach:

    Optimized Approach

    1. **Sorting Method**: Sort each word and use the sorted word as a key in a hash map. All anagrams will have the same sorted key.

    2. **Character Count Method**: Use the frequency of characters in each word as a key in a hash map. This avoids the need to sort the words.

    Sorting Method

    1. Initialize an empty hash map to store groups of anagrams. 2. For each word in the input list: - Sort the word. - Use the sorted word as a key and append the original word to the list of anagrams in the hash map. 3. Collect all the values from the hash map and return them as the result.

    Algorithm

    Let's break down the sorting method step-by-step:

    1. Initialize an empty hash map `unordered_map>`.
    2. Iterate through each word in the input list.
    3. Sort the characters of the word to form the key.
    4. Insert the original word into the hash map using the sorted word as the key.
    5. After processing all words, collect all the values from the hash map and return them.

    Code Implementation

    #include <iostream>
    #include <vector>
    #include <string>
    #include <unordered_map>
    #include <algorithm>
    
    using namespace std;
    
    vector<vector<string>> groupAnagrams(vector<string>& strings) {
        // Hash map to store groups of anagrams
        unordered_map<string, vector<string>> anagramGroups;
        
        // Iterate through each word in the input list
        for (string& word : strings) {
            // Sort the word to form the key
            string sortedWord = word;
            sort(sortedWord.begin(), sortedWord.end());
            
            // Insert the original word into the hash map
            anagramGroups[sortedWord].push_back(word);
        }
        
        // Collect all the values from the hash map
        vector<vector<string>> result;
        for (auto& group : anagramGroups) {
            result.push_back(group.second);
        }
        
        return result;
    }
    
    int main() {
        vector<string> strings = {"eat", "tea", "tan", "ate", "nat", "bat"};
        vector<vector<string>> result = groupAnagrams(strings);
        
        // Print the result
        for (const auto& group : result) {
            cout << "[";
            for (const auto& word : group) {
                cout << word << " ";
            }
            cout << "]" << endl;
        }
        
        return 0;
    }
    

    Complexity Analysis

    The time complexity of the sorting method is O(n * L * log L), where n is the number of words and L is the maximum length of a word. This is because we sort each word, which takes O(L * log L) time, and we do this for all n words.

    The space complexity is O(n * L) because we store all the words in the hash map.

    Edge Cases

    Potential edge cases include:

    • Empty input list: The function should return an empty list.
    • Single word input: The function should return a list containing a single group with that word.
    • All words are anagrams: The function should return a single group containing all words.

    Testing

    To test the solution comprehensively, consider the following test cases:

    • Simple cases with a few words.
    • Cases with no anagrams.
    • Cases with all words being anagrams.
    • Edge cases like empty input or single word input.

    Thinking and Problem-Solving Tips

    When approaching such problems, consider the following tips:

    • Understand the problem requirements and constraints thoroughly.
    • Think about different ways to represent the problem (e.g., sorting, character counts).
    • Consider the time and space complexity of different approaches.
    • Practice solving similar problems to improve problem-solving skills.

    Conclusion

    Grouping anagrams is a common problem that can be efficiently solved using hash maps and sorting. Understanding different approaches and their complexities is crucial for optimizing solutions. Practice and familiarity with such problems can significantly enhance problem-solving skills.

    Additional Resources

    For further reading and practice, consider the following resources:

    Keep going with C++About 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free