49. 字母异位词分组
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的所有字母得到的一个新单词。
输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
输入: strs = [""]
输出: [[""]]
输入: strs = ["a"]
输出: [["a"]]
方法一
vector<vector<string>> groupAnagrams(vector<string>& strs) {
// 自定义对 array<int, 26> 类型的哈希函数
auto arrayHash = [fn = hash<int>{}] (const array<int, 26>& arr) ->
size_t {
return accumulate(arr.begin(), arr.end(), 0u, [&](size_t acc, int num)
{
return (acc << 1) ^ fn(num);
});
};
unordered_map<std::array<int, 26>, vector<string>, decltype(arrayHash)> strMap(0, arrayHash);
for(string str : strs)
{
std::array<int, 26> count{};
for(int i = 0; i < str.size(); i++)
{
count[int(str[i] - 'a')]++;
}
strMap[count].emplace_back(str);
}
vector<vector<string>> result;
for(auto it = strMap.begin(); it != strMap.end(); it++)
{
result.emplace_back(it->second);
}
return result;
}
主要对自定义哈希函数分析:定义了一个lambda
函数arrayHash
,它接受一个array<int, 26>
类型的数组作为参数,并返回一个size_t类型的哈希值。fn
是一个名为hash<int>
的哈希函数对象,用于对数组元素执行哈希操作。accumulate
算法对数组元素进行累加,并执行自定义的哈希算法。这里的acc表示累加结果的初始值,num表示当前遍历到的数组元素。
在这个哈希算法中,每个元素通过fn(num)
调用哈希函数对象来获取其哈希值,然后将累加结果左移一位(acc << 1)
后与元素的哈希值进行异或操作(^)
。这样,每个元素的哈希值都会被依次加入到累加结果中。最终,累加结果将作为这个数组的哈希值返回。
这种方式可以将数组的各个元素结合起来计算出唯一的哈希值,以满足unordered_map或unordered_set等数据结构的要求。
方法二
class Solution {
public:
//根据字符串生成哈希串 如abcc a1b1c2
string getHashKey(string str)
{
int count[26]{0};
for(int i = 0; i < str.size(); i++)
{
count[int(str[i] - 'a')]++;
}
ostringstream s;
for(int i = 0; i < 26; i++)
{
if(count[i] > 0)
s << char('a' + i) << count[i];
}
return s.str();
}
vector<vector<string>> groupAnagrams(vector<string>& strs) {
unordered_map<string, vector<string>> strMap{};
for(const string str : strs)
{
string hashKey = getHashKey(str);
strMap[hashKey].emplace_back(str);
}
vector<vector<string>> result;
for(auto it = strMap.begin(); it != strMap.end(); it++)
{
result.emplace_back(it->second);
}
return result;
}
};