方法一:字符串排序
字母异位词指的是两个单词的字符组成相同,字符的排列顺序不同,由此可推断,这两个词经过内部字符排序后的结果是相同的,[nat -> ant] [tan -> ant]。将排序后的词语作为map的key值,map的value存储排序后结果相同的单词。
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
vector<vector<string>> res;
unordered_map<string, vector<string>> stringmap;
for(auto _str : strs)
{
string tmp = _str;
sort(tmp.begin(), tmp.end());
stringmap[tmp].emplace_back(_str);
}
for(auto _map : stringmap)
{
res.emplace_back(_map.second);
}
return res;
}
};
方法二:字符计数
每个单词的字符组成相同顺序不同,那么组成单词的字母种类和数量是相同的,可以将字母和数字作为map的key值,字符种类和数量相同的单词存储到map的value中。
下面是官方代码:
class Solution {
public:
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<array<int, 26>, vector<string>, decltype(arrayHash)> mp(0, arrayHash);
for (string& str: strs) {
array<int, 26> counts{};
int length = str.length();
for (int i = 0; i < length; ++i) {
counts[str[i] - 'a'] ++;
}
mp[counts].emplace_back(str);
}
vector<vector<string>> ans;
for (auto it = mp.begin(); it != mp.end(); ++it) {
ans.emplace_back(it->second);
}
return ans;
}
};
作者:力扣官方题解
链接:https://leetcode.cn/problems/group-anagrams/solutions/520469/zi-mu-yi-wei-ci-fen-zu-by-leetcode-solut-gyoc/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
【代码解释】:
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);
});
};
上述部分的代码是定义array<int, 26>类型数组的哈希值,用两个嵌套的lambda表达式实现。第一个lambda表达式创建了一个hash<int>类型的变量fn用于在表达式内部调用,声明了参数const array<int, 26>& arr,返回值类型是size_t,函数体实现的功能是累加数组内部单个元素的哈希值。第二个lambda表达式实现的是对数组中单个元素进行哈希值的计算,用acc<<1^fn(num)的方式减少冲突。
unordered_map<array<int, 26>, vector<string>, decltype(arrayHash)> mp(0, arrayHash);
上述代码定义了unordered_map的变量。定义arrayHash的目的是为了让unordered_map接受array<int, 26>作为键值。默认情况下,std::unordered_map 的键需要支持 std::hash,但 std::hash 并未针对 std::array 这种容器类型提供默认实现。因此,自定义哈希函数是为了使 unordered_map 能够处理 std::array<int, 26> 类型的键。