1.思路一:将字符串按照统一的(从小到大)规则进行排序,以排序后的字符串为键借助哈希表进行分组
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
//定义一个哈希表用于存放结果
unordered_map<string, vector<string>> ht;
//使用迭代器遍历字符串数组strs
for(auto &it: strs){
string sorted_s = it;//将每一个字符串进行复制
ranges::sort(sorted_s);//对复制的字符串进行从小到大排序
//sort(sorted_s.begin(), sorted_s.end());
ht[sorted_s].push_back(it);//将排序后字符串相等的字符串分到同一组,
//即以排序后的字符串为键,以原字符串组成的列表为值
//ht[sorted_s].emplace_back(it);
}
vector<vector<string>> a;//构建一个新容器a用于存放结果
a.reserve(ht.size());//预留和哈希表中值相等的空间
//将哈希表ht中的值部分提取出来
for(auto it = ht.begin(); it != ht.end(); it++){
a.push_back(it->second);
}
// for (auto &[_, v] : ht) {
// a.push_back(v);
// }
return a;
}
};
针对相似函数的解释:
push_back()与emplace_back()
两者都适用于向支持动态扩展的容器的末尾增加一个元素,如
std::vector
和std::deque,
但是
push_back()
:
接受一个现有对象作为参数。
需要将提供的对象拷贝(或移动)到容器中。
对于复杂类型,存在不必要的性能开销。
emplace_back()
:
接受构造函数的参数,直接在容器末尾构造对象。
避免了临时对象的创建和拷贝。
对于复杂类型,效率更高。
当你已经有了一个现成的对象,并希望将其添加到容器时使用
push_back()
当你希望直接构造一个对象,并将其添加到容器时使用
emplace_back()
以下是一个自定义类型中两函数的对比示例:
vector<Person> people; // 使用 push_back() Person p1("Alice", 30); people.push_back(p1); // 需要调用拷贝构造函数 // 使用 emplace_back() people.emplace_back("Bob", 25); // 直接构造对象
for (auto &[_, value] : m)与for(auto it = ht.begin(); it != ht.end(); it++)
前者使用结构化绑定(C++17 引入),不需要显式调用迭代器,可以直接访问键和值,并进行修改:
- 将
unordered_map
的每个元素(键值对)解构为键和值的引用:
_
:占位符表示键(可以命名为其他变量名)。value
:引用表示值(可以直接操作值)。后者通过迭代器手动遍历容器,每个
it
是指向容器元素(键值对)的迭代器。
访问键和值:
- 使用
it->first
访问键。- 使用
it->second
访问值。
2.思路二:遍历字符串数组,记录每个字符串中26个字母出现的次数,以26个字母出现的次数为键借助哈希表进行分组
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
//思路:记录26个字母在每个字符串中出现的次数,借助哈希表进行分组
unordered_map<string, vector<string>> ht;
for(auto &s: strs){//使用迭代器访问字符串数组
//定义一个count数组记录26个字母出现的次数
int count[26] = {0};
for(auto &e: s){//使用迭代器访问每一个字符串
count[e-'a']++;
}
//定义一个字符串将26个字母出现次数统计起来
string key = "";
for(int i = 0; i < 26; i++){
if(count[i] != 0){
key.push_back('a'+i);
key.push_back(count[i]);
}
}
//以26个字母出现次数为键,以字符串为值插入哈希表
ht[key].push_back(s);
}
vector<vector<string>> r;
r.reserve(ht.size());
for(auto it = ht.begin(); it != ht.end(); it++){
r.push_back(it->second);
}
return r;
}
};