题目
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的所有字母得到的一个新单词。
示例
示例 1:
输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"] 输出: [["bat"],["nat","tan"],["ate","eat","tea"]]示例 2:
输入: strs = [""] 输出: [[""]]示例 3:
输入: strs = ["a"] 输出: [["a"]]
分析
同一组字母异位词中的字符串具备相同点,可以使用相同点作为一组字母异位词的标志。使用哈希表来解决,哈希表的键为字母异位词的标志,哈希表的值为字母异位词列表。
排序法
排序后的字母异位词相同,因此可以将这些排序后的字符串作为键。
时间复杂度:O(),
是字符串数量,
是字符串最大长度
空间复杂度:O(),
是字符串数量,
是字符串最大长度
unordered_map<string, vector<string>> anagramMap;
// 遍历每个字符串
for (string& str : strs) {
// 将每个字符串排序
string sortedStr = str;
sort(sortedStr.begin(), sortedStr.end());
// 将排序后的字符串作为key,加入字母异位词的组
anagramMap[sortedStr].push_back(str);
}
// 从哈希表中提取所有的值
vector<vector<string>> result;
for (auto& pair : anagramMap) {
result.push_back(pair.second);
}
return result;
计数法
互为字母异位词的字母频率相同,因此可以将字母计数结果作为键。
时间复杂度:O(),
是字符串数量,
是字符串最大长度
空间复杂度:O(),
是字符串数量,
是字符串最大长度
unordered_map<string, vector<string>> anagramMap;
// 遍历每个字符串
for (string& str : strs) {
// 创建一个大小为26的数组来存储字母频率
vector<int> charCount(26, 0);
// 统计当前字符串每个字符的频率
for (char c : str) {
charCount[c - 'a']++;
}
// 将字符频率数组转换为字符串作为哈希表的键
string key = "";
for (int count : charCount) {
key += to_string(count) + "#"; // 使用 "#" 来分隔每个字符的频率
}
// 将当前字符串加入到对应字符频率的组中
anagramMap[key].push_back(str);
}
// 从哈希表中提取所有的值
vector<vector<string>> result;
for (auto& pair : anagramMap) {
result.push_back(pair.second);
}
return result;
知识充电
auto& pair : container
是一种非常常见且有效的遍历容器元素的方法,适用于任何需要高效访问容器元素的情况,尤其是在元素类型较为复杂时。通过使用引用,避免了不必要的拷贝操作,从而提高了性能。