难度中等
给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。
思路:
最开始看到示例中的输入,感觉输入中可能存在大量重复的字符串,考虑使用map记录当前字符串的数量,然后匹配其他长度一致的字符串,相同则加入向量并标记。
代码如下:运行至第 111/112 个输入样例时运行超时
vector<vector<string>> groupAnagrams(vector<string>& strs) {
vector<vector<string>> ans;
int m[strs.size()];
memset(m,false,sizeof(m));
for(int i=0;i<strs.size();++i){
if(m[i]) continue;
int len=strs[i].size();
ans.push_back(vector<string>());
for(int j=i;j<strs.size();++j){
if(len!=strs[j].size()) continue;
bool add=true;
unordered_map<char,int> temp;
for(auto c:strs[i]){
temp[c]++;
}
for(auto c:strs[j]){
if(!temp[c]--){ add=false; continue; }// 如何返回而不会加入到其中
}
if(add) {ans.back().push_back(strs[j]); m[j]=true;}
}
}
return ans;
}
更新思路:勉强实现功能
考虑将重新生成一个字符串向量,将其中每个字符串排序,该字符串相等,则将原始字符串加入结果中,并标记为已添加项(即后续不处理)
vector<vector<string>> groupAnagrams(vector<string>& strs) {
vector<vector<string>> ans;
vector<string> data=strs;
int len=strs.size();
for(int i=0;i<len;++i){
sort(data[i].begin(),data[i].end());
}
bool M[len];
memset(M,false,sizeof(M));
for(int i=0;i<len;++i){
if(M[i]) continue;
ans.push_back(vector<string>());
for(int j=i;j<len;++j){
if(data[j]!=data[i]) continue;
ans.back().push_back(strs[j]);
M[j]=true;
}
}
return ans;
}
参考思路:
我个人仅考虑到字符串中各元素相加,但是结果可能会存在重复,某大佬则引入了质数相乘的概念,确保了各字符串一定不会出现相同结果。
vector<vector<string>> groupAnagrams(vector<string>& strs) {
vector<vector<string>> ans;
unordered_map <double,vector<string> > M;
double a[26]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101};
for(string& s : strs)
{
double temp = 1;
for(char c : s)
temp *= a[c - 'a'];
M[temp].push_back(s); // temp为单词对应的质数乘积,M[temp]为该单词的异位词构成的vector
}
for(auto& index : M) // index为键和值组成的pair
ans.push_back(index.second);
return ans;
}