Given an array of strings strs
, group the anagrams together. You can return the answer in any order.
Example 1:
Input: strs = ["eat","tea","tan","ate","nat","bat"]
Output: [["bat"],["nat","tan"],["ate","eat","tea"]]
Explanation:
"bat"
."nat"
and "tan"
are anagrams as they can be rearranged to form each other."ate"
, "eat"
, and "tea"
are anagrams as they can be rearranged to form each other.Example 2:
Input: strs = [""]
Output: [[""]]
Example 3:
Input: strs = ["a"]
Output: [["a"]]
Constraints:
1 <= strs.length <= 104
0 <= strs[i].length <= 100
strs[i]
consists of lowercase English letters.The problem asks to group anagrams together from a given array of strings. Anagrams are words or phrases formed by rearranging the letters of another. The solution involves using a hash table (or dictionary in Python) to efficiently group the anagrams.
This approach leverages the fact that anagrams have the same letters, regardless of their order. Therefore, if we sort the letters of each string alphabetically, anagrams will have identical sorted strings.
Time Complexity: O(n * k * log k), where n is the number of strings and k is the maximum length of a string. Sorting each string takes O(k * log k) time, and we do this for n strings.
Space Complexity: O(n * k) in the worst case, where all strings are unique (no anagrams), resulting in a hash table with n entries, each storing a string of length k.
This approach avoids sorting. It uses character counts as the key for the hash table.
Time Complexity: O(n * k), where n is the number of strings and k is the maximum length of a string. We iterate through each string once to count characters.
Space Complexity: O(n * k) in the worst case (similar to Approach 1), as each string might be stored in the hash table.
Approach 1 (Sorting):
Python:
from collections import defaultdict
class Solution:
def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
anagram_dict = defaultdict(list)
for s in strs:
sorted_s = "".join(sorted(s))
anagram_dict[sorted_s].append(s)
return list(anagram_dict.values())
Java:
import java.util.*;
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
Map<String, List<String>> anagramMap = new HashMap<>();
for (String str : strs) {
char[] charArray = str.toCharArray();
Arrays.sort(charArray);
String sortedStr = new String(charArray);
anagramMap.computeIfAbsent(sortedStr, k -> new ArrayList<>()).add(str);
}
return new ArrayList<>(anagramMap.values());
}
}
C++:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <map>
using namespace std;
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
map<string, vector<string>> anagramMap;
for (string& str : strs) {
string sortedStr = str;
sort(sortedStr.begin(), sortedStr.end());
anagramMap[sortedStr].push_back(str);
}
vector<vector<string>> result;
for (auto const& [key, val] : anagramMap) {
result.push_back(val);
}
return result;
}
};
Approach 2 (Character Counting): Similar code can be written for Approach 2 in Python, Java, and C++, using character count arrays or strings as keys instead of sorted strings. The core logic remains the same – using a hash table to group strings based on their character counts.