news 2026/2/11 4:12:42

哈希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/2/10 15:42:39

Dify自定义工具部署成功率达99%?这才是真正的端点配置终极方案

第一章&#xff1a;Dify自定义工具端点配置的核心价值 在构建智能化应用的过程中&#xff0c;Dify平台通过其灵活的自定义工具端点配置能力&#xff0c;显著提升了开发者对AI工作流的掌控力。该功能允许用户将外部服务以标准化方式集成至AI代理中&#xff0c;使大模型能够动态调…

作者头像 李华
网站建设 2026/2/6 0:40:29

OCR行业落地新趋势:cv_resnet18_ocr-detection多场景应用解析

OCR行业落地新趋势&#xff1a;cv_resnet18_ocr-detection多场景应用解析 1. 引言&#xff1a;OCR技术进入轻量化落地新阶段 在数字化转型加速的今天&#xff0c;OCR&#xff08;光学字符识别&#xff09;早已不再是实验室里的高冷技术&#xff0c;而是深入到金融、物流、教育…

作者头像 李华
网站建设 2026/2/5 15:05:51

2.【SV】SystemVerilog TestBench

芯片验证&#xff1a;手把手教你搭建测试平台 测试平台&#xff08;Testbench&#xff09;是验证工程师的主战场。用最接地气的方式&#xff0c;理解测试平台的每一个组件。 一、测试平台&#xff1a;芯片的“模拟驾驶舱” 什么是测试平台&#xff1f; 想象你要测试一辆新车&am…

作者头像 李华
网站建设 2026/1/30 18:41:41

Paraformer-large适合嵌入式吗?边缘设备部署可行性分析

Paraformer-large适合嵌入式吗&#xff1f;边缘设备部署可行性分析 1. 引言&#xff1a;Paraformer-large语音识别的潜力与挑战 你有没有想过&#xff0c;让一台没有联网的小设备也能听懂人话&#xff1f;比如家里的智能音箱、工厂里的巡检机器人&#xff0c;甚至是一台老旧的…

作者头像 李华
网站建设 2026/2/7 23:28:27

springboot174基于Java的高校学生课程预约成绩统计系统的设计与实现

目录具体实现截图摘要系统所用技术介绍写作提纲源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;具体实现截图 摘要 随着高校教育信息化建设的不断推进&#xff0c;传统的学生课程预约与成绩统计方式已无法满足高效、精准的管理需求。基…

作者头像 李华
网站建设 2026/2/8 15:24:23

springboot181基于SSM 旅游平台的设计与实现

目录具体实现截图摘要系统所用技术介绍写作提纲源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;具体实现截图 摘要 随着互联网技术的快速发展&#xff0c;旅游行业逐渐向信息化、智能化方向转型。传统的旅游服务模式存在信息不对称、预…

作者头像 李华