问题描述:
给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。
示例:
输入: ["eat", "tea", "tan", "ate", "nat", "bat"]
,
输出:
[
["ate","eat","tea"],
["nat","tan"],
["bat"]
]
说明:
- 所有输入均为小写字母。
- 不考虑答案输出的顺序。
基本思路:
以按照升序排列的字符串作为键。以vector类型作为value来进行分组。
AC代码:
class Solution {
public:
string ChangeOrder(string str) {
// 返回字符升序排序的字符串
string res;
map<char, int> hashmap;
for (char ch : str) {
++hashmap[ch];
}
// 按照自然顺序遍历
for (char ch = 'a'; ch <= 'z'; ++ch) {
for (int i = 0; i < hashmap[ch]; ++i) {
res += ch;
}
}
return res;
}
vector<vector<string>> groupAnagrams(vector<string>& strs) {
map<string, vector<string>> hashmap;
for (string str : strs) {
hashmap[ChangeOrder(str)].push_back(str);
}
vector<vector<string>> res;
for (auto it = hashmap.begin(); it != hashmap.end(); ++it) {
res.push_back(it->second);
}
return res;
}
};
大牛的思路:
以上代码我们花了相当长的时间来传递字符串副本。
与其把所有结果保存在hashmap,再把结果逐一复制到vector中。
不如直接操作vector。hashmap中存放的就是与我们vector有关的信息。
(这里存放的是在vector的行数)
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
unordered_map<string,int>index;
vector<vector<string>> result;
for(auto i:strs)
{
//sort(i.begin();i.end());
string tmp = i;
sort(tmp.begin(),tmp.end());
if(index.find(tmp)==index.end())
{
index.insert({tmp,(int)result.size()});
result.push_back(vector<string>{i});
}
else
{
result[index[tmp]].push_back(i);
}
}
return result;
}
};
其他经验:
- 不妨直接在返回的结果集上进行操作,免得创建副本浪费时空间。
- 我对字符串中各个字符的排序使用了计数排序的方法,其实我们用sort效率会更高。
- 我们可以使用hashmap来进行分组,其中的key就是我们组的标示。value就是组中的成员的集合。