原题目
给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。
示例:
输入: [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”],
输出:
[
[“ate”,“eat”,“tea”],
[“nat”,“tan”],
[“bat”]
]
说明:
所有输入均为小写字母。
不考虑答案输出的顺序。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/group-anagrams
题目大意
可以理解为只要单词的每个字符出现次数相同时就放在一个数组里,归为一类。
题目分析
排序法:
对每个字符串按ASCII码进行排序,这样就可以更方便比较字符串是否是一类。
简单来说:
首先,从第一个字符串开始循环。
第二,对字符串进行排序。
第三,对字符串与排好序的数组进行一一比较,将不重复字符串存入数组中,代表该字符串在空间中的位置。
第四,既然知道字符串空间中的位置,就按位置放入要返回的数组中。
例子:
原数组strs:【“eat”,“tea”,“tan”,“ate”,“nat”,“bat”】
返回数组str1:
【
[“ate”,“eat”,“tea”],
[“nat”,“tan”],
[“bat”]
】
str2:临时存储每个字符串排序的值
将排序后的字符串存入数组且排序后相同的字符串不存入str3数组
str3:【“aet”,“ant”,“abt”】
str4:临时存储字符串的数组,因str1是二维string类数组,无法直接将strs[i]字符串压入,所以现将其压入str4数组里,在将str4压入str1中,C++其他操作还不熟悉,先这样用。
过程描述:
第一次:
strs【0】=【“eat”】;//找到第一个值
str2=“aet”;//排序后
str3【】=【“aet”】;//存储排序后的值,表示该字符串的位置
str4【】=【“eat”】;//临时存储第一个值,变成一维数组
str1【】=【【“eat”】】;//通过str3的空间位置,压入字符串
第二次:
strs【1】=【“tea”】;
str2=“aet”;
str3【】=【“aet”】;
str4【】=【“tea”】;
str1【】=【【“eat”,“tea”】】;
第三次:
strs【2】=“tan”;
str2=“ant”;
str3【】=【“aet”,“ant”】;
str4【】=【“ant”】;
str1【】=【
【“eat”,“tea”】
【“tan”】
】;
第四次:
strs【3】=“ate”;
str2=“ant”;
str3【】=【“aet”,“ant”】;
str4【】=【“ate”】;
str1【】=【
【“eat”,“tea”,“ate”】
【“tan”】
】;
。。。。
第六次
strs【3】=“bat”;
str2=“abt”;
str3【】=【“aet”,“ant”,“abt”】;
str4【】=【“bat”】;
str1【】=【
【“eat”,“tea”,“ate”】
【“tan”,“nat”】
【“bat”】
】;
以此类推
哈希+排序法:用hash法就不需要每次循环比较,用排序后的字符串作为下标,直接找到该字符串属于哪一空间即可。
完整代码
排序法:
class Solution
{
public:
vector<vector<string>> groupAnagrams(vector<string>& strs)
{
vector<vector<string>>str1;
string str2;
vector<string>str3;
int next=0,site;
for(int i=0; i<strs.size(); i++)//从第一个字符串开始,通过下面的方法,存储在相对应的str1中
{
int flag=1;
str2=strs[i];
sort(str2.begin(),str2.end());
//得到此时排序后的字符串存入str2中
for(int j=0; j<str3.size(); j++)//与str3中的所有排好序的数组一一比较
{
if(str2==str3[j])
//如果str2与str3中的字符串相等,说明在这个字符串前就找到与它异位的字符串,用flag标记,并用site记录异位字符串存储的位置,以便将该字符串存储在异位字符串的后面
{
flag=0;
site=j;//site就是字符串在一位空间的位置
break;
}
}
if(flag==1)//如果在此之前不存在异位字符串,就开创一个新空间存储,否则接在异位的空间后面
{
str3.push_back(str2);//将排好序的当前字符串str2存入str3
vector<string>str4;
str4.push_back(strs[i]);//str4保存当前字符
str1.push_back(str4);
}
else
{
str1[site].push_back(strs[i]);
}
}
return str1;
}
};
哈希法:
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
unordered_map<string,vector<string>>hash;
for(auto s:strs)
{
string str1=s;
sort(str1.begin(),str1.end());
hash[str1].push_back(s);
}
int len=hash.size();
vector<vector<string>>res(len);
int k=0;
for(auto i:hash)
{
res[k++]=i.second;
}
return res;
}
};
总结
了解排序和哈希,学习C++hash的用法。