当前位置: 首页 > news >正文

字母异位词分组(每天刷力扣hot100系列)

题目介绍:

方法1:遍历法 

#include <algorithm>class Solution {
public:vector<vector<string>> groupAnagrams(vector<string>& strs) {vector<string> beg(strs);for (string& k : beg) sort(k.begin(), k.end());  // 排序作为键vector<vector<string>> rel;vector<bool> visited(strs.size(), true);  // 使用visited标记for(int i=0;i<beg.size();i++){vector<string> temp;if(visited[i]==true){temp.push_back(strs[i]);for(int j=i+1;j<beg.size();j++){if(beg[i]==beg[j]){temp.push_back(strs[j]);visited[j]=false;}}rel.push_back(temp);}}return rel;}
};

(博主自己敲的方法,不推荐,适合理解)

代码思路

1. 创建beg数组,是strs的拷贝,然后对beg中的每个字符串进行排序(这样同一个变位词组排序后字符串相同)。

2. 然后遍历beg数组,对于每个字符串,如果它是true,则创建一个临时组,将当前字符串加入(注意:这里加入的是排序后的字符串,但实际需要的是原字符串)。 3. 然后内层循环从i+1开始,找后面所有与beg[i]相同的字符串,将对应的原字符串(strs[j])加入临时组,并将beg[j]标记为false(表示已经处理过)。

4. 最后将临时组加入结果rel中。

 

方法2:哈希桶

class Solution {
public:vector<vector<string>> groupAnagrams(vector<string>& strs) {//哈希桶unordered_map<string,vector<string>> mp;//创建一个字符串和字符串数组对应键值的哈希表for(auto str:strs)//迭代器将数组里的字符串全部排序,然后在对应的字符串键处存放原字符串{string key=str;sort(key.begin(),key.end());mp[key].push_back(str);//这里如果用emplace_back内存消耗更少}vector<vector<string>> rel;for(auto it=mp.begin();it!=mp.end();it++)//遍历哈希桶{rel.push_back(it->second);//将字符串组插入rel中,这里如果用emplace_back内存消耗更少}return rel;}
};

复杂度分析

1.时间复杂度O(nklogk),其中 n 是 strs 中的字符串的数量,k 是 strs 中的字符串的的最大长度。需要遍历 n 个字符串,对于每个字符串,需要 O(klogk) 的时间进行排序以及 O(1) 的时间更新哈希表,因此总时间复杂度是 O(nklogk)。

2.空间复杂度O(nk),其中 n 是 strs 中的字符串的数量,k 是 strs 中的字符串的的最大长度。需要用哈希表存储全部字符串。

 

核心区别

特性push_back()emplace_back()
工作原理构造临时对象 → 拷贝/移动到容器直接在容器内存中构造对象
参数接受对象本身接受对象的构造参数
效率可能额外构造临时对象(有拷贝开销)避免临时对象(更高效)
适用场景添加已存在的对象直接构造新对象

这个方法不同的是不需要根据每个的字符串往后遍历,而是直接放进哈希桶,最后把vector<string>提出来就行。

 

力扣上还有个计数的方法比较复杂,但是时间复杂度和空间复杂度进一步降低了:

方法3:计数

class Solution {
public:vector<vector<string>> groupAnagrams(vector<string>& strs) {// 自定义对 array<int, 26> 类型的哈希函数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);});};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;}
};

复杂度分析

1.时间复杂度:O(n(k+∣Σ∣)),其中 n 是 strs 中的字符串的数量,k 是 strs 中的字符串的的最大长度,Σ 是字符集,在本题中字符集为所有小写字母,∣Σ∣=26。需要遍历 n 个字符串,对于每个字符串,需要 O(k) 的时间计算每个字母出现的次数,O(∣Σ∣) 的时间生成哈希表的键,以及 O(1) 的时间更新哈希表,因此总时间复杂度是 O(n(k+∣Σ∣))。

2.空间复杂度:O(n(k+∣Σ∣)),其中 n 是 strs 中的字符串的数量,k 是 strs 中的字符串的最大长度,Σ 是字符集,在本题中字符集为所有小写字母,∣Σ∣=26。需要用哈希表存储全部字符串,而记录每个字符串中每个字母出现次数的数组需要的空间为 O(∣Σ∣),在渐进意义下小于 O(n(k+∣Σ∣)),可以忽略不计。

 

喜欢的话就关注我吧~~~求关注求赞求收藏~~~^-^

 

http://www.dtcms.com/a/308979.html

相关文章:

  • 即时通讯系统项目面试可能的考点
  • 对git 熟悉时,常用操作
  • QT收费情况
  • 谷歌V3插件热更新
  • 类与对象(上),咕咕咕
  • 【Node】nvm在windows系统无管理员权限切换node版本
  • 20250731在荣品的PRO-RK3566开发板的Android13下跑通敦泰的FT8206触控芯片
  • 【Java EE初阶 --- 网络原理】网络层---IP协议,数据链路层---以太网协议
  • OpenCV学习day2
  • YodA数据集的格式化(二)
  • MySQL 8.0 OCP 1Z0-908 题目解析(39)
  • 项目中如何追踪项目进度,避免项目延期如何追踪项目进度
  • 尚硅谷尚庭公寓学习笔记
  • 《P2910 [USACO08OPEN] Clear And Present Danger S》
  • JVM之【Java虚拟机概述】
  • uniapp中uview组件中u-input格式化后赋值踩坑
  • 网站技术攻坚与Bug围剿手记
  • nodejs——在Express中使用Session认证
  • 基于 AXI-Lite 实现可扩展的硬件函数 RPC 框架(附完整源码)
  • graph attention network
  • Sklearn 机器学习 文本数据 计数向量化加入停用词
  • Spring Boot 项目问题:Web server failed to start. Port 5566 was already in use.
  • Linux应用开发基础知识——Makefile初级教程(九)
  • 订单识别与发票识别结合的技术实现方案
  • 最新PS 2025安装包下载与安装教程(Adobe Photoshop 2025 )
  • Java客户端连接Redis
  • langchain--2--invoke、batch、stream、ainvoke、abatch、astream
  • 51c自动驾驶~合集12
  • Python脚本批量将usdz文件转为glb文件
  • 智能体通信协议