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

LeetCode hot100:049 字母异位词分组:两种解法的深度解析

问题描述:

给你一个字符串数组,请你将字母异位词组合在一起。可以按任意顺序返回结果列表。(字母异位词是指由相同字母重排列形成的字符串)

示例1:

输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]输出: [["bat"],["nat","tan"],["ate","eat","tea"]]解释:在 strs 中没有字符串可以通过重新排列来形成 "bat"。
字符串 "nat" 和 "tan" 是字母异位词,因为它们可以重新排列以形成彼此。
字符串 "ate" ,"eat" 和 "tea" 是字母异位词,因为它们可以重新排列以形成彼此。

示例2:

输入: strs = [""]输出: [[""]]

示例3:

输入: strs = ["a"]输出: [["a"]]

解决方法:

方法一:排序+哈希表

核心:将每个字符串排序,排序后的字符串作为字母异位词的键。

步骤:①创建哈希表,键为排序后的字符串,值为原字符串列表;

           ②遍历每个字符串,将其排序后作为键;

           ③将原字符串添加到对应键的列表中;

           ④返回哈希表的值。

示例:

处理第一个字符串s = "eat"
sorted("eat") = ['a', 'e', 't']
key = "aet"
groups["aet"] = ["eat"]

groups = { "aet": ["eat"]}

整体流程:

输入: ["eat", "tea", "tan", "ate", "nat", "bat"]

处理流程:
"eat"  -> 排序 "aet" -> 分组1: ["eat"]
"tea"  -> 排序 "aet" -> 分组1: ["eat", "tea"]  
"tan"  -> 排序 "ant" -> 分组2: ["tan"]
"ate" ->  排序 "aet" -> 分组1: ["eat", "tea", "ate"]
"nat"  -> 排序 "ant" -> 分组2: ["tan", "nat"]
"bat" ->  排序 "abt" -> 分组3: ["bat"]

最终分组:
分组1: ["eat", "tea", "ate"]   (键: "aet")
分组2: ["tan", "nat"]             (键: "ant")  
分组3: ["bat"]                      (键: "abt")

适用性:字符串长度较小或中等。

方法二:计数+哈希表

核心:统计每个字符串中字母的出现次数,用计数数组作为字母异位词的键。

步骤:①创建哈希表,键为计数数组的元组形式,值为原字符串列表;

           ②遍历每个字符串,统计26个字母的出现次数;

           ③将计数数组转换为元组作为键;

           ④将原字符串添加到对应键的列表中作为值;

           ⑤返回哈希表的值

示例:对于“eat”来说

字符: e -> index = ord('e') - ord('a') = 4
字符: a -> index = ord('a') - ord('a') = 0  
字符: t -> index = ord('t') - ord('a') = 19

count数组变化:
每一个字符串的初始数组: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
e:    [0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
a:    [1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
t:     [1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0]

适用性:大数据量,性能要求高。

算法详解:

方法一:

class Solution:def groupAnagrams(self, strs: List[str]) -> List[List[str]]:from collections import defaultdict #导入defaultdict,用于创建默认值为列表的字典groups = defaultdict(list) #实例化一个defaultdict,当访问不存在的键时自动创建空列表作为值for s in strs:key = ''.join(sorted(s))groups[key].append(s)return list(groups.values()) #将字典中的值转换为列表返回

其中,sorted() 函数将字符串中的每个字符单独取出并排序,返回结果是按字母顺序排列的字符列表。而 ' ' .join() 则是将字符列表连接成一个字符串,空字符串 ' '表示字符之间不加任何分隔符。

复杂度分析:

  • 时间复杂度:O(n × k) n 是字符串数量,k 是字符串平均长度,k logk是每个字符串排序。
  • 空间复杂度:O(n × k) 存储所有字符串和哈希表。

方法二:

class Solution:def groupAnagrams(self, strs: List[str]) -> List[List[str]]:from collections import defaultdict #导入defaultdict,用于创建默认值为列表的字典groups = defaultdict(list) #实例化一个defaultdict,当访问不存在的键时自动创建空列表作为值for s in strs:count = [0] * 26 #创建长度为26的列表,统计26个小写字母出现次数 初始化全零for ch in s:index = ord(ch) - ord('a') #计算字符在count列表中的索引位置count[index] +=1key = tuple(count) #计数列表转换为元组,列表不可作为字典的键groups[key].append(s)return list(groups.values())

在Python语言中,字符不能直接进行算数运算,要使用 ord() 函数进行ASCII计算。而在C语言或C++中可以直接表示,Java中类型自动隐式转换。

复杂度分析:

  • 时间复杂度:O(n × k) n 是字符串数量,k 是字符串平均长度 。
  • 空间复杂度:O(n × k) 存储所有字符串和哈希表

 总结:

  1. 哈希表是核心:两种方法都利用哈希表实现高效分组;
  2. 标识选择:方法一选择排序后的字符串,方法二选择计数数组;
  3. 性能方面:方法一代码更简洁,并且同样适用于字符串中包含大写字母的情况,方法二在大数据量时性能更好。

通过这个问题,更重要的是掌握利用统一标识进行分组的通用解题思路。

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

相关文章:

  • 网站建设业务前景政务信息网站建设制度
  • 使用C#写微信小程序后端——电商微信小程序
  • C++——vector容器、动态容器
  • C++ 类与对象(下篇)笔记整理
  • 重庆建站服务商漳浦网站开发
  • 深入浅出理解电感:从理论到实践的电路“惯性”元件
  • 分布式事务:基于MQ事务的解决方案详解
  • 无信息先验:贝叶斯分析中的客观基准
  • 公司官网备案流程mysql优化 wordpress
  • 网站建设员课程注册网页版
  • 瑞莎星瑞(Radxa Orion O6) 基于 Android OS 使用 NPU的图片模糊查找APP 开发
  • 户外商品网站制作长沙网站建设的公司
  • 安卓13_ROM修改定制化-----ROM解打包 修改 讲解 导读篇
  • 网站设计亮点望野亭
  • RTC时钟原理
  • STM32运行原理深度解析:从软件到硬件的神奇之旅
  • OpenCV(十一):色彩空间转换
  • 广州安全教育平台网宁波网站seo哪家好
  • 家装网站自己做的平面设计常用网站
  • Three.js轨道控制器完全指南(OrbitControls与TrackballControls)
  • 服务器数据恢复—硬盘黄灯预警,RAID5阵列数据如何恢复?
  • CATIA 转换为 3DXML 全流程:迪威模型网在线转换和本地方转换方法指南
  • 学校门户网站建设的意义做任务分享赚钱的网站
  • 网站个人中心wordpress怎么做手机网站
  • 杂记 15
  • Video Understanding Baseline via papers
  • MySQL架构和存储引擎
  • Zabbix模板,自定义键值监控项,图形
  • 前端js 常见算法面试题目详解
  • 盾思途旅游网站建设免费seo工具