leetocode做题笔记|49字母异位词分组

原题链接

解题思路:两个字符串互为字母异位词,当且仅当两个字符串包含的字母相同。同一组字母异位词中的字符串具备相同点,可以使用相同点作为一组字母异位词的标志,使用哈希表存储每一组字母异位词,哈希表的键为一组字母以为此的标志,哈希表的值为一组字母异位词列表

遍历每个字符串,对于每个字符串,得到该字符串所在的一组字母异位词的标志,将当前字符串加入该组字母异位词的列表中。遍历全部字符串之后,哈希表中每个键值对即为一组字母异位词。

以下的两种方法分别使用排序和计数作为哈希表的键。

方法一:排序

由于互为字母异位词的两个字符串包含的字母相同,因此对两个字符串分别进行排序之后得到的字符串一定是相同的,故可以将排序之后的字符串作为哈希表的键。

先创建一个哈希表,遍历strs,将遍历得到的每个字符串排序(排列后顺序会变成a~z),在哈希表“abbc”这个key下的2维vector储存了“abcb”,"acbb"这两个字符串再遍历一遍哈希表,将哈希表中的二维vector添加进答案中

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
       unordered_map<string,vector<string>>mp;
//遍历字符串数组
  for(string& str:strs){
     //设置一个中间变量记录每一个字符串
    string key = str;
     //进行排序,因为相同的单词中所包含的字母一定是相同的
    sort(key.begin(),key.end());
     //在哈希表中寻找排完序单词的位置,如果找不到就创建该位置
     //并将此时原字符串插入到哈希表中
    mp[key].emplace_back(str);
     }

  //设置二维字符串数组
   vector<vector<string>>ans;
   //对哈希表进行遍历,将每一个对应的value值加入到二维字符串数组 
   for(auto it = mp.begin(); it != mp.end();++it){
       ans.emplace_back(it->second);
      }
      //返回二维字符串数组
           return ans;
    }
};

方法二:计数

由于互为字母以为此的两个字符串包含的字母相同,因此两个字符串中的相同字母出现的次数一定是相同的,故可以将每个字母出现的次数使用字符串表示,作为哈希表的键。

由于字符串只包含小写字母,因此对于每个字符串,可以使用长度为26的数组记录每个字母出现的次数。需要注意的是,在使用数组作为哈希表的键时,不同语言的支持程度不同,因此实现方式也不同。

源代码:

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
//定义一个哈希表,哈希表的键为 字符串中每个字母出现的次数
    auto arrayHash = [fn = hash<int>{}](const array<int,26>&arr) -> size_t{
        return accumulate(arr.begin(),arr.end(),0u,[&](size_t acc,int num){
            return (acc << 1)^fn(num);
        });
    };


//使用长度为26的数组对每个字符串,记录这个字符串中每个字母出现的次数
    unordered_map<array<int,26>,vector<string>,decltype(arrayHash)>mp(0,arrayHash);
    for(string& str: strs){
        array<int,26>counts{};
        int length = str.length();
        for(int i = 0; i < length; ++i){
            counts[str[i] - 'a'] ++;
        }
        mp[counts].emplace_back(str);
    }
    vector<vector<string>>ans;
    for(auto it = mp.begin();it != mp.end(); ++it){
        ans.emplace_back(it -> second);
    }
    return ans;
    }
};

  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值