
🧑💻博主名称:鱼子星_
✅数据结构专栏:【数据结构】
✅算法竞赛专栏:【算法竞赛】
✅C++系列专栏:【C++从零开始系列】
2. 字母异位词分组
题目描述
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
样例
示例 1:
输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
解释:
- 在 strs 中没有字符串可以通过重新排列来形成 "bat"。
- 字符串 "nat" 和 "tan"是字母异位词,因为它们可以重新排列以形成彼此。
- 字符串 "ate" ,"eat" 和 "tea"是字母异位词,因为它们可以重新排列以形成彼此。
示例 2:
输入: strs = [""]
输出: [[""]]
示例 3:
输入: strs = ["a"]
输出: [["a"]]
解题思路
💡解法一:排序 + 哈希表
不管异位排列的字符串有多少个样式,对它们单独排序完之后,都是一样的字符串。例如:["ate","eat","tea"] 排序完成后都是 "aet"
所以,可以遍历字符串数组,对每个字符串单独的排序后,插入到哈希表中,最后将哈希表中的所有元素插入到要返回的二维数组中即可。
🗋 代码
cpp
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
unordered_map<string, vector<string>> mp;
for(int i = 0; i < strs.size(); i++)
{
string s = strs[i];
sort(s.begin(), s.end());
mp[s].push_back(strs[i]);
}
vector<vector<string>> ret;
for(auto t : mp)
{
ret.push_back(t.second);
}
return ret;
}
};
LeetCode官方代码
cpp
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
unordered_map<string, vector<string>> mp;
for (string& str: strs) {
string key = str;
sort(key.begin(), key.end());
mp[key].emplace_back(str);
}
vector<vector<string>> ans;
for (auto it = mp.begin(); it != mp.end(); ++it) {
ans.emplace_back(it->second);
}
return ans;
}
};
提交结果

💡解法二:计数 + 哈希表
不管排列的方式有多少种,只要组成相同的字符串,它们 26 个字母出现的次数肯定是相同的,只需要使用数组记录每个字符串 26 个字母出现的次数,将相同的分在一起就可以了
🗋 代码
cpp
class Solution {
public:
string calc(string& s, vector<int>& a)
{
string t = "";
for(int i = 0; i < s.size(); i++)
{
int t = s[i] - 'a';
a[t]++;
}
for(int i = 0; i < 26; i++) t.push_back(a[i] + '0');
return t;
}
vector<vector<string>> groupAnagrams(vector<string>& strs)
{
int n = strs.size();
unordered_map<string, int> mp;
//给哈希表开辟空间
vector<vector<int>> hash(n);
for(int i = 0; i < n; i++)
hash[i].resize(26);
//填表
int cnt = 0;
vector<vector<string>> ret;
for(int i = 0; i < n; i++)
{
string t = calc(strs[i], hash[i]);
if(mp.count(t)){
ret[mp[t]].push_back(strs[i]);
}else{
mp[t] = cnt++;
vector<string> st;
st.push_back(strs[i]);
ret.push_back(st);
}
}
return ret;
}
};
LeetCode官方代码
cpp
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;
}
};
提交结果
