说人话的leetcode.049 字母异位词分组

先看原题

题目给的中等,其实也就比上一篇博客发的那个略微难一点而已。

一、那这里先介绍一个超好用的方法:sort(),算法题里应该可以使用吧。

sort() 是 C++ 标准库中的一个排序函数,可以快速将数组、容器(如 vector)中的元素按照你想要的顺序排列。例如:

  • 将 [3,1,4,2] 排序为 [1,2,3,4](升序)
  • 将 ["banana", "apple"] 排序为 ["apple", "banana"](字典序)

所以你看,这玩意多智能?

基本语法:

#include <algorithm> // 必须包含这个头文件
using namespace std; // 使用标准命名空间

sort(起始地址, 结束地址的下一位, 比较函数(可选));
  • 起始地址:要排序的第一个元素的位置(指针或迭代器)
  • 结束地址的下一位:要排序的最后一个元素的下一个位置
  • 比较函数(可选):自定义排序规则,默认是升序

举例说明:

#include <iostream>
#include <algorithm> // 引入头文件
using namespace std;

int main() 
{
    int arr[] = {3, 1, 4, 2};
    int n = sizeof(arr) / sizeof(arr[0]); // 计算数组长度

    sort(arr, arr + n); // 排序:起始地址是arr,结束地址是arr+n

    // 输出结果:1 2 3 4
    for (int i = 0; i < n; i++) {
        cout << arr[i] << " ";
    }
    return 0;
}

随便定义一个数组,然后计算一下数组的长度

这里使用sort排序,默认升序。

注意,里面传入的一定是地址!

输出一定是1,2,3,4.

以下注意:

  • arr 是数组首地址,arr + n 是最后一个元素的下一位地址。

  • sort(arr, arr + n) 表示对整个数组升序排序。

ok这下我们有了个巨好用的工具了。那么就很简单了。

这题你看,有没有可能,我们先给他排个序?是把每一个字符串都给他排个序?

这里再次说明一个东西叫C风格字符串,如果是常量的话可以简单理解为一个叫const char* 数组。

就是一个字符数组不就是一个字符串嘛,字面意思。

诶,那么对于每一个在原本的大数组的元素:

进来后给这个字符串自己排序(C风格字符串)

排序后,这不就齐活了吗?

所有的元素都是统一的格式,但是每一个人的顺序都没乱,那么接下来就简单了。

在刚才排序后定义一个保存结果的数组,这个数组的形式在题解的那个函数类型已经给了提示,

是一个以vector<string>为元素类型的vector数组。用来保存重新匹配配对后的结果。

这里还有个马后炮,在前面那个给每一个元素排序的时候,按照key,把元素也塞进去

key:组成这个元素的字母组合,也就是排序后的字符串

value:这个元素自己,没排序的值

所以很明显前面得有一个东西拷贝原本的元素,然后那这个拷贝的排序,排序完后根据这个拷贝,作为key,把本尊作为value放进哈希表。

然后呢,再把哈希表的value给到result。

我知道这个时候可能就有人要问了,主包主包,你的哈希表为什么一个key值能有多个value

有没有可能,那个哈希表的value,其实是一个数组?

狗头。

后面还有一点:那就是把value pop出来的时候记得用move()

虽然我也不懂为啥,但是好像说很厉害的样子。

完整代码如下:

vector<vector<string>> groupAnagrams(vector<string>& strs) {
    // 创建哈希表,键是排序后的字符串,值是分组列表
    unordered_map<string, vector<string>> groups;

    // 遍历所有字符串
    for (const string& s : strs) {
        // 对当前字符串排序生成键
        string key = s;        // 复制原字符串
        sort(key.begin(), key.end()); // 排序字符

        // 将原始字符串加入对应分组
        groups[key].push_back(s);
    }

    // 收集所有分组到结果中
    vector<vector<string>> result;
    for (auto& pair : groups) { // pair 是键值对
        result.push_back(std::move(pair.second)); // 移动语义优化
    }

    return result;
}

函数定义

cpp

vector<vector<string>> groupAnagrams(vector<string>& strs) {
  • 输入参数是字符串数组的引用 strs
  • 返回值是二维字符串数组,表示分组后的结果。
3. 创建哈希表

cpp

unordered_map<string, vector<string>> groups;
  • groups 的键是排序后的字符串(string),值是对应的分组列表(vector<string>)。
4. 遍历所有字符串

cpp

for (const string& s : strs) {
  • 使用范围 for 循环逐个处理输入字符串 s
5. 生成排序后的键

cpp

string key = s;        // 复制原字符串
sort(key.begin(), key.end());
  • 将原字符串复制到 key(避免直接修改原字符串)。
  • 对 key 的字符排序(例如 "tea" → "aet")。
6. 将字符串加入分组

cpp

groups[key].push_back(s);
  • 以 key 为键,将原字符串 s 添加到对应的分组列表中。
  • 如果 key 不存在,unordered_map 会自动创建一个空列表。
7. 收集所有分组到结果

cpp

vector<vector<string>> result;
for (auto& pair : groups) {
    result.push_back(std::move(pair.second));
}
  • result 是最终返回的分组列表。
  • 遍历哈希表的每个键值对 pair,将分组列表 pair.second 移动到 result 中。
  • 移动语义优化std::move 避免复制整个 vector,提高效率。

三、总结关键内容

1.sort();

2.unordered_map()

3.move()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值