续上文找到报错原因之后,更一下49题详细过程,感觉对算法理解又加深了一步。
https://blog.csdn.net/qq_40286920/article/details/124612597?spm=1001.2014.3001.5502
0.浅聊一下unordered_map
- unordered_map中所有的元素都是pair(对组)
- pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)
- unordered_map中不允许有重复元素。
- unordered_map的底层结构是哈希表。
而C++ STL 标准库中,不仅是 unordered_map 容器,所有无序容器的底层实现都采用的是哈希表存储结构。更准确地说,是用“链地址法”(又称“开链法”)解决数据存储位置发生冲突的哈希表。(也就是同一个key的val会以链表的形式存储,如下图P1,P2,P3的key都是0)
1.题目描述:
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次。
示例:
输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
翻译成人话:
输入:test = {"eat", "tea", "tan", "ate", "nat", "bat"};
输出:
2.题解思路:
利用unordered_map,对每一个源字符串进行排序(同一个分组的异位词排序后相同!!!)。排序后的字符串作为key(索引),将源字符串(未排序的)作为val,以链式结构存放在相应的key后边。
举例,如图从左往右看:
3.本地实现
#include<iostream>
#include<string>
#include<map>
#include<unordered_map>
#include<vector>
#include<algorithm>//sort()需要
using namespace std;
class Solution
{
public:
vector<vector<string>> groupAnagrams(vector<string>& strs)
{
unordered_map<string, vector<string>> mp;//创建一个无序unordered_map,将排序后的string作为key,原string作为val;
for (string& str : strs)//创建一个str依次接受strs里的字符串。string& 和 string 的区别:string是拷贝,string&是直接引用修改本身
{
string key = str; //拷贝给key
sort(key.begin(), key.end());//对key进行排序
mp[key].push_back(str); //把源字符串放在相同的key对应的val。 unordered_map采用开链式结构
}
//从哈希表中取出相同key的val,按依次放在vector<vector>容器中
vector<vector<string>> ans;//建立一个容器ans来存放结果
for (unordered_map<string, vector<string>>::iterator it = mp.begin(); it != mp.end(); it++)
{//unordered_map<string, vector<string>>::iterator 等价于 auto
ans.push_back(it->second);//it->first表示key;it->second表示val;
}
return ans;
}
};
int main()
{
Solution solution;
vector<string> test = {"eat", "tea", "tan", "ate", "nat", "bat"};
vector<vector<string>> res = solution.groupAnagrams(test);
//遍历大容器
for (vector<vector<string>>::iterator it = res.begin(); it != res.end(); it++)
{ //遍历小容器
for (vector<string>::iterator vit = (*it).begin(); vit != (*it).end(); vit++)//(*it)表示容器 vecotr<string>
{ //遍历字符串
for (string::iterator vvit = (*vit).begin(); vvit != (*vit).end(); vvit++)
{
cout << (*vvit);
}
cout << " ";
}
cout << endl;
}
system("pause");
return 0;
}
再放一种计数的方法:和我之前做的思路一致。被push论文就不多讲了,不清楚的点这里!
https://blog.csdn.net/qq_40286920/article/details/124541380?spm=1001.2014.3001.5502
原理如图:
class Solution2
{
public:
vector<vector<string>> groupAnagrams(vector<string>& strs)
{//容器里不能for(int i = 0; i<;i++)
map<vector<int>, vector<string>> mp;
for (string& str : strs)
{
vector<int> table(26, 0);
for (auto it = str.begin(); it != str.end(); it++)
{
table[(*it)-'a']++;
}
mp[table].push_back(str);
}
vector<vector<string>> ans;
for (auto it = mp.begin(); it != mp.end(); it++)
{
ans.push_back(it->second);//it->first表示key;it->second表示val;
}
return ans;
}
};