LeetCode 49. 字母异位词分组
题目描述
相关标签:哈希表、字符串、排序
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的所有字母得到的一个新单词。
示例
示例 1:
输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"], ["nat", "tan"], ["ate", "eat", "tea"]]
示例 2:
输入: strs = [""]
输出: [[""]]
示例 3:
输入: strs = ["a"]
输出: [["a"]]
提示
1 <= strs.length <= 10^40 <= strs[i].length <= 100strs[i]仅包含小写字母
解题思路
字母异位词的核心特征是:每个字符串中包含的字母种类和数量完全相同,只是顺序可能不同。因此,我们需要找到一种方法来标识一组字母异位词。常见方法包括:
- 排序法:将每个字符串的字符排序后作为键(key),相同的键对应一组字母异位词。
- 计数法:统计每个字符串中每个字母出现的次数,形成一个特征值作为键来分组。
- 质数乘积法:为每个字母分配一个唯一的质数,计算字符串中所有字母对应质数的乘积,作为键来分组。
以下我们重点分析基于 排序法 的解法,并提供代码实现。
代码实现(排序法)
class Solution:
def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
map = {}
for s in strs:
key = ''.join(sorted(s)) # 对字符串排序作为键
if key not in map:
map[key] = []
map[key].append(s)
return list(map.values()) # 直接返回字典的值列表
代码解析
- 初始化字典:使用
map字典来存储分组结果,键是排序后的字符串,值是对应的字母异位词列表。 - 遍历字符串数组:对输入数组
strs中的每个字符串s进行处理。 - 生成键:将字符串
s的字符排序后拼接成一个新字符串key,确保字母异位词有相同的键。例如,"eat"和"tea"排序后都变为"aet"。 - 分组:如果
key不在字典中,初始化一个空列表;然后将当前字符串s添加到对应键的列表中。 - 返回结果:最后返回字典中所有值的列表,即分组后的结果。
复杂度分析
- 时间复杂度:
O(n * k * log k)n是字符串数组strs的长度。k是单个字符串的最大长度,排序一个长度为k的字符串需要O(k * log k)的时间。- 总时间复杂度为遍历
n个字符串,每个字符串排序所需时间之和。
- 空间复杂度:
O(n)- 用于存储分组结果的字典
map需要O(n)的空间,具体取决于输入字符串的数量和分组情况。
- 用于存储分组结果的字典
优点与缺点
- 优点:逻辑简单,易于理解和实现;适用于大多数场景。
- 缺点:排序操作
O(k * log k)存在优化空间,尤其当字符串较长时,性能可能不如计数法。
替代解法对比
1. 计数法
思路:统计每个字符串中每个字母的出现次数,形成一个特征值作为键,避免排序操作。
代码:
class Solution:
def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
map = {}
for s in strs:
count = [0] * 26 # 统计每个字母的出现次数
for char in s:
count[ord(char) - ord('a')] += 1
key = str(count) # 将计数数组转为字符串作为键
if key not in map:
map[key] = []
map[key].append(s)
return list(map.values())
- 时间复杂度:
O(n * k),计数操作是线性时间。 - 空间复杂度:
O(n)。 - 优点:比排序法更快,尤其在字符串较长时。
2. 质数乘积法
思路:为每个字母分配一个唯一质数,计算字符串中字母对应质数的乘积作为键。
代码:
class Solution:
def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101]
map = {}
for s in strs:
product = 1
for char in s:
product *= primes[ord(char) - ord('a')]
if product not in map:
map[product] = []
map[product].append(s)
return list(map.values())
- 时间复杂度:
O(n * k)。 - 空间复杂度:
O(n)。 - 缺点:可能存在整数溢出问题(Python 中无此问题),可读性稍差。
332

被折叠的 条评论
为什么被折叠?



