news 2026/4/18 10:55:51

哈希2:字母异位符分组

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
哈希2:字母异位符分组

🎯 题目描述

给定一个字符串数组,将所有字母异位词组合在一起。字母异位词指的是由相同字母重排形成的字符串,例如"eat""tea"。可以按任意顺序返回结果列表。

💡 核心思路

要解决这个问题,关键是找到一种统一的标识,让所有字母异位词都对应同一个标识,这样就能用哈希表把它们分组。

我这里提供两种主流思路:

1. 排序法(直观易实现)

  • 核心逻辑:将每个字符串排序,排序后的结果相同的字符串就是字母异位词。例如"eat""tea"排序后都是"aet"
  • 时间复杂度:\(O(nk\log k)\),其中 n 是字符串数量,k 是单个字符串的最大长度。排序每个字符串需要 \(O(k\log k)\),共 n 个字符串。
  • 空间复杂度:\(O(nk)\),用于存储哈希表和结果。

2. 字符计数法(更优时间复杂度)

  • 核心逻辑:统计每个字符串中 26 个字母的出现次数,用一个包含计数的字符串作为哈希表的键。例如"eat"的计数是a:1, e:1, t:1,可以表示为"1#0#0#...#1#1"
  • 时间复杂度:\(O(nk)\),统计每个字符串的字符计数只需 \(O(k)\),共 n 个字符串。
  • 空间复杂度:\(O(nk)\),用于存储哈希表和结果。

🚀 完整代码实现

排序法(AC 代码)

cpp

#include <vector> #include <string> #include <unordered_map> #include <algorithm> using namespace std; class Solution { public: vector<vector<string>> groupAnagrams(vector<string>& strs) { // 哈希表:键为排序后的字符串,值为对应的字母异位词列表 unordered_map<string, vector<string>> groups; for (string& s : strs) { string sorted_s = s; // 排序字符串,得到统一标识 sort(sorted_s.begin(), sorted_s.end()); // 将原字符串加入对应分组 groups[sorted_s].push_back(s); } // 将哈希表中的值转移到结果中 vector<vector<string>> result; result.reserve(groups.size()); // 预分配空间,提升效率 for (auto& [_, group] : groups) { result.push_back(move(group)); // 使用move避免拷贝 } return result; } };

字符计数法(更优时间复杂度)

cpp

#include <vector> #include <string> #include <unordered_map> using namespace std; class Solution { public: vector<vector<string>> groupAnagrams(vector<string>& strs) { unordered_map<string, vector<string>> groups; for (string& s : strs) { // 统计26个字母的出现次数 vector<int> count(26, 0); for (char c : s) { count[c - 'a']++; } // 将计数转换为字符串作为键 string key; for (int i = 0; i < 26; ++i) { key += to_string(count[i]) + '#'; } groups[key].push_back(s); } vector<vector<string>> result; for (auto& [_, group] : groups) { result.push_back(move(group)); } return result; } };

📝 关键细节解析

  1. 结构化绑定auto& [_, group]这是 C++17 引入的语法,用于遍历哈希表时直接提取键值对。_作为占位符表示我们不需要使用键,group直接引用值(字母异位词列表),避免了拷贝,提升了效率。

  2. reserve预分配空间在创建结果vector时,调用reserve(groups.size())可以提前分配足够的内存,避免后续push_back时频繁扩容,从而提升性能。

  3. std::move避免拷贝在将哈希表中的vector转移到结果时,使用std::move可以将vector的所有权直接转移,而不是进行昂贵的深拷贝。


🧪 测试用例验证

以题目示例输入strs = ["eat","tea","tan","ate","nat","bat"]为例:

  • 排序法中,"eat""tea""ate"排序后均为"aet",会被分到同一组。
  • 字符计数法中,它们的字符计数完全相同,也会被分到同一组。最终输出:[["bat"],["nat","tan"],["ate","eat","tea"]],与题目要求一致。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 6:24:46

2024年AI图像处理趋势:开源cv_unet_image-matting+弹性GPU实战指南

2024年AI图像处理趋势&#xff1a;开源cv_unet_image-matting弹性GPU实战指南 1. 引言&#xff1a;为什么2024年抠图技术迎来爆发&#xff1f; 你有没有遇到过这样的场景&#xff1a;想做个电商主图&#xff0c;但模特背景太杂乱&#xff1b;想换个头像发朋友圈&#xff0c;可…

作者头像 李华
网站建设 2026/4/18 6:25:14

为什么FSMN VAD总检测失败?参数调优实战教程入门必看

为什么FSMN VAD总检测失败&#xff1f;参数调优实战教程入门必看 你是不是也遇到过这种情况&#xff1a;明明音频里有清晰的说话声&#xff0c;FSMN VAD却一点反应都没有&#xff1f;或者语音被莫名其妙地截断&#xff0c;片段切得支离破碎&#xff1f;别急&#xff0c;这并不…

作者头像 李华
网站建设 2026/4/18 7:04:09

企业级声纹平台:基于CAM++的微服务架构设计

企业级声纹平台&#xff1a;基于CAM的微服务架构设计 1. 引言&#xff1a;为什么需要企业级声纹识别系统&#xff1f; 在金融、安防、智能客服等高安全要求的场景中&#xff0c;传统的密码或短信验证方式已无法满足日益增长的身份核验需求。而声纹识别技术&#xff0c;凭借其…

作者头像 李华
网站建设 2026/4/18 6:57:45

强烈安利专科生必用AI论文写作软件TOP9

强烈安利专科生必用AI论文写作软件TOP9 2026年专科生论文写作工具测评&#xff1a;为何要关注AI写作软件&#xff1f; 随着人工智能技术的不断发展&#xff0c;AI写作工具逐渐成为学术写作中不可或缺的辅助工具。对于专科生而言&#xff0c;撰写论文不仅是一项重要的学习任务&a…

作者头像 李华
网站建设 2026/4/17 7:00:32

cv_unet_image-matting透明噪点太多?Alpha阈值优化实战指南

cv_unet_image-matting透明噪点太多&#xff1f;Alpha阈值优化实战指南 1. 问题背景&#xff1a;为什么抠图总有“毛边”和透明噪点&#xff1f; 你有没有遇到这种情况&#xff1a;用AI工具把人像从背景里抠出来&#xff0c;结果边缘一圈全是半透明的杂色像素&#xff0c;像是…

作者头像 李华