LeetCode49 字母异位词分组

原题目

给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。
示例:
输入: [“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的用法。

你可能感兴趣的:(#,string,LeetCode算法题解)