现在已将LeetCode刷题心得记录github上,每一题都有我能够想到的多种解法,欢迎star!github
本题主要是对字符串分类,要求如下
首先可以利用哈希的方式解决,给每一个字母一个特定的质数,那么一个字母组合基本上对应唯一的哈希值,根据哈希值插入即可
class Solution {
public:
int strFind(map<char,int>&m,string s,vector<int>&hash)
{
long tmp=1;
for(int i=0;i<s.size();i++)
{
tmp*=m[s[i]];
if(tmp>INT_MAX) tmp=tmp%INT_MAX;
}
for(int i=0;i<hash.size();i++)
{
if(hash[i]==tmp) return i;
}
hash.push_back(tmp);
return -1;
}
vector<vector<string>> groupAnagrams(vector<string>& strs) {
map<char,int> m;
m['a']=2;
m['b']=3;
m['c']=5;
m['d']=7;
m['e']=11;
m['f']=13;
m['g']=17;
m['h']=19;
m['i']=23;
m['j']=29;
m['k']=31;
m['l']=37;
m['m']=41;
m['n']=43;
m['o']=47;
m['p']=53;
m['q']=59;
m['r']=61;
m['s']=67;
m['t']=71;
m['u']=73;
m['v']=79;
m['w']=83;
m['x']=97;
m['y']=101;
m['z']=103;
vector<vector<string>>ans;
vector<int>hash;
int pos;
for(int i=0;i<strs.size();i++)
{
pos=strFind(m,strs[i],hash);
if(pos!=-1)
{
ans[pos].push_back(strs[i]);
}
else{
vector<string> line;
line.push_back(strs[i]);
ans.push_back(line);
}
}
return ans;
}
};
但是这种方法在对INT_MAX取余之后会有一定概率出现冲突,而且这种方法只能解决这种26个英文字母的方式,总感觉很蠢,而且运行时间88ms,只能打败10.8%用户。
仔细思考后发现,每个分类集合里面的字符串只是顺序不同而已,排个序利用map映射不就行了,于是采用如下方法:
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
vector<vector<string>>ans;
unordered_map<string,vector<string>>mp;
for(auto s:strs)
{
string t=s;
sort(t.begin(),t.end());
mp[t].push_back(s);
}
for(auto line:mp)
{
ans.push_back(line.second);
}
return ans;
}
};
这样更加普适,并且不会存在冲突,时间效率只要24ms