问题描述
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的所有字母得到的一个新单词。
示例一:
输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
示例二:
输入: strs = [""]
输出: [[""]]
示例三:
输入: strs = ["a"]
输出: [["a"]]
原因分析:
给出的一个字符串数组,要找到相同的字母组成的字符串分为一组;
难点:找到一组字符串的相同点
解决方案:
因为要找到字符串中字母组成一样的字符串组合在一起,于是先预处理每一个strs里面的字符串的每个字母出现的次数,然后查找每一个字符串中的出现次数相等的,组合在一起。
时间复杂度:O(n∗n)
空间复杂度:O(n∗n)
Tip:
1:添加 ans.push_back(vector<string>()); // 添加一个空的一维向
才可以进行ans[cnt].push_back(strs[i]);要不然根本不存在ans[0]之类的。
在这里要特别注意一点,力扣的刷题常用到vector,当设定为一维数组时,例如vector<int> ans (n);
特别注意红线部分,否则ans不能像使用数组一样来使用下标(还不存在)。
2:
int st[n];
int h[n][30];
memset(st,0,sizeof st);//特别注意这里要加上初始化为0!!
memset(h,0,sizeof h);//特别注意这里要加上初始化为0!!!
要注意初始化。
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs){
vector<vector<string>> ans;
int n=strs.size();
int cnt=0;
int st[n];
int h[n][30];
memset(st,0,sizeof st);//特别注意这里要加上初始化为0!!
memset(h,0,sizeof h);//特别注意这里要加上初始化为0!!!
//vector< vector<int>> h;
for(int i=0;i<n;i++){
for(int j=0;j<strs[i].size();j++){
h[i][strs[i][j]-'a']++; //存下每一个值的字母出现的次数
}
}
// for(int i=0;i<n;i++){
// for(int j=0;j<strs[i].size();j++){
// cout<<h[i][strs[i][j]-'a']<<" "; //存下每一个值的字母出现的次数
// }
// cout<<endl;
// }
for(int i=0;i<n;i++){
if(!st[i]) {
ans.push_back(vector<string>()); // 添加一个空的一维向
ans[cnt].push_back(strs[i]);
st[i]=1;
}
else continue;
for(int j=0;j<n;j++){
int flag=false;
for(int k=0;k<30;k++){
if(h[i][k]==h[j][k]) continue;
else {
flag=true;
break;
}
}
if(!flag&&!st[j]){
ans[cnt].push_back(strs[j]);
st[j]=true;
}
}
cnt++;
}
return ans;
// for(int i=0;i<n;i++){
// long long res=0;
// for(int j=0;j<strs[i].size();j++){
// res=res*p+strs[i][j];
// }
// h[i]=res;
// }
// for(int i=0;i<h.size();i++){
// ans[i].push_back(strs[i]);
// for(int j=0;j<h.size();j++){
// if(h[i]==h[j]) ans[i].push_back(strs[j]);
// }
// }
// return ans;
}
};