49. Group Anagrams
Given an array of strings, group anagrams together.
Example:
Input: ["eat", "tea", "tan", "ate", "nat", "bat"]
,
Output:
[
["ate","eat","tea"],
["nat","tan"],
["bat"]
]
Note:
- All inputs will be in lowercase.
- The order of your output does not matter.
题目链接:https://leetcode.com/problems/group-anagrams/
n为string数,k为单个string长度。
法一:对string排序
时间复杂度:nklogk
空间复杂度:nk
对字符串补偿的情况表现好。
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
unordered_map<string,int> record;
vector<vector<string>> res;
for(int i =0; i<strs.size();++i){
string tmp = strs[i];
sort(tmp.begin(),tmp.end());
if(record.find(tmp)!=record.end()){
res[record[tmp]].push_back(strs[i]);
}else{
record[tmp] = res.size();
vector<string> subres = {strs[i]};
res.push_back(subres);
}
}
return res;
}
};
法二:每个串转为字符出现次数统计串
此法相当于把sort改进为了计算字母出现次数,从klogk降到k,其他步骤和法一一样。
但貌似实际运行结果反而变差了??难道是我打开方式不对???
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
unordered_map<string,int> record;
vector<vector<string>> res;
for(int i =0; i<strs.size();++i){
string tmp = cal(strs[i]);
if(record.find(tmp)!=record.end()){
res[record[tmp]].push_back(strs[i]);
}else{
record[tmp] = res.size();
vector<string> subres = {strs[i]};
res.push_back(subres);
}
}
return res;
}
string cal(string s){
int res[26]={0};
for(int i=0;i<s.length();++i){
res[s[i]-'a']++;
}
string sres="";
for(int i=0;i<26;++i){
sres+=res[i];
sres+='#';
}
return sres;
}
};
法三:拆解成两个字符串的Anagram问题
从头开始,两层for循环,对没有分好类的字符串,比较二者的字符分布情况。
这里把sort的klogk复杂度改进为k,但在比较次数上上升了,最坏的情况是每个串是单独一类,复杂度就上升到了 (n^2)k
因此这种方法在串数量大、串变化复杂的情况不适用。
且实际运行证明这种思路确实超时不可行,无论是两层for循环的方法,还是只对类别对应代表串比较的方法。
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
unordered_map<string,int> record;
vector<vector<string>> res;
for(int i =0; i<strs.size();++i){
bool isNew = true;
for(int j=0;j<res.size();++j){
if(isEqual(res[j][0],strs[i])){
isNew = false;
res[j].push_back(strs[i]);
break;
}
}
if(isNew){
vector<string> subres={strs[i]};
res.push_back(subres);
}
}
return res;
}
bool isEqual(string s1, string s2){
unordered_map<char,int> record;
for(int i=0;i<s1.length();++i){
record[s1[i]]++;
}
for(int i=0;i<s2.length();++i){
record[s2[i]]--;
if(record[s2[i]]<0) return false;
}
return true;
}
};