字母异位词 是由重新排列源单词的所有字母得到的一个新单词。
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表
输入: strs =["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
1 <= strs.length <= 104
0 <= strs[i].length <= 100
strs[i]
仅包含小写字母
最简单的思路,把每个串进行排序然后扔进hashset中
异构字符串 s1, s2 | -sorting-> 相同字符串s1', s2'
std::vector<std::vector<std::string>>
anagrams(std::vector<std::string>& collection){
std::vector<std::vector<std::string>> result {};
std::unordered_map<std::string, std::vector<std::string>> hash {};
for(auto const & s : collection){
auto t { s };
std::ranges::sort(t);
hash[t].emplace_back(s);
}
for(auto &[__dummy, __vec] : hash) result.emplace_back(std::move(__vec));
return result;
}
排序和拷贝有开销
可以采用rehash的思路,异构字符串的定义指出,两个字符串只要包含同种且同数目的小写字母,即互为异构
string | -hashing-> counter[26] {...} | -hashing-> unique_hash_value
std::vector<std::vector<std::string>>
anagrams(std::vector<std::string>& collection){
static constexpr auto SIGMA { 26U };
auto anagrams_hash = [fn = std::hash<int>{}](const std::array<int, SIGMA>& arr) -> std::size_t{
return std::accumulate(arr.begin(), arr.end(), 0U, [&](std::size_t __acc, int current){
return (acc << 1) ^ fn(current);
});
};
std::unordered_map<std::array<int, SIGMA>, std::vector<std::string>, decltype(anagrams)>
hash(0U, anagrams);
for(auto const & s : collection){
std::array<int, SIGMA> counter {};
for(auto const & c : s) counter[c - 'a'] ++;
hash[counter].emplace_back(s);
}
std::vector<std::vector<std::string>> result {};
for(auto & [__dummy, __vec] : hash) result.emplace_back(std::move(__vec));
return result;
}