跳到正文
第 49 题中等

字母异位词分组

Group Anagrams

把字符串数组按字母异位词分组;字母相同、顺序不同视为同一组。

在力扣中练习

题目描述

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。

 

示例 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"]]

 

提示:

  • 1 <= strs.length <= 104
  • 0 <= strs[i].length <= 100
  • strs[i] 仅包含小写字母

解题思路

主解法

排序键 + 哈希表

异位词排序后长得一模一样

最直接的做法是两两比较两个单词是否互为异位词,时间是 O(n² · k),单词一多就慢。

关键观察:两个单词互为异位词,当且仅当它们排序后的字符串相同。于是可以给每个单词算一个规范键,用哈希表把键相同的单词收集到一起。

自拟主例 ["abc","bca","cab","dog","god","x"]:前三个都排序成 abc,dog 和 god 都排序成 dgo,x 单独成组。

分步图解

"abc" 排序后是 "abc",新建一组。

key
abc
组数
1
strs
0
1
2
3
4
5
abc
bca
cab
dog
god
x
i
排序后的字符串是分组键
groups(key → 单词)
abc→abc
键相同的单词归为一组
1 / 3
abc、bca、cab 排序后都是 abc,连续并入同一组。

每个单词排序 O(k log k),哈希查找期望 O(1),总时间 O(n · k log k),空间 O(n · k)。键相同的单词直接追加,不需要再回头比较。

分步图解

"dog" 排序后是 "dgo",新建一组。

key
dgo
组数
2
strs
0
1
2
3
4
5
abc
bca
cab
dog
god
x
i
排序后的字符串是分组键
groups(key → 单词)
abc→abc, bca, cab
dgo→dog
键相同的单词归为一组
1 / 3
dog 与 god 共用 dgo;x 单独成组。

如果字符集很小(例如只有小写字母),可以用 26 个计数拼成键,把排序的 O(k log k) 降到 O(k)。

时间 O(n · k log k)空间 O(n · k)

易错点

  • 直接对原字符串排序:会打乱输出顺序,题目要求组内保留原单词。
  • 用字符和当键:abc 与 aad 的字符和可能相同,会错误合并。
  • 把空串漏掉:空串排序后仍是空串,应单独成组。
对照解法

计数键 · 不排序

用 26 个字母的出现次数当指纹

时间从 O(n · k log k) 降到 O(n · k),代价是键更长(26 个计数),适合字符集固定且单词较长的情况。

排序键要付出 O(k log k)。如果字符集固定为 26 个小写字母,可以直接统计每个字母出现几次,把这 26 个数字拼成字符串当键。

例如 abc 和 cab 的计数都是 1#1#1#0#...,键相同;aad 的计数是 2#0#1#...,不会和 abc 混淆。

每个单词扫描一遍 O(k),拼键 O(26),总时间 O(n · (k + 26)),空间仍是 O(n · k)。计数键比分隔符要选好,避免 1, 11 和 11, 1 这类拼接歧义。

  1. 1对每个单词统计 26 个字母的出现次数。
  2. 2把计数用分隔符拼成 key。
  3. 3按 key 放入哈希表。
  4. 4收集所有分组。
时间 O(n · (k + 26))空间 O(n · k)

易错点

  • 计数拼键不加分隔符:不同计数可能拼成同一个字符串。
  • 只处理小写字母:题目若含大写或数字,需要扩大计数表。

代码与演示

主解法配有图解;对照解法用于比较思路、复杂度或实现方式。

演示输入strs = ["abc","bca","cab","dog","god","x"]

groups 为空;逐个读入单词,把字符排序后得到的字符串当键。

组数
0
strs
0
1
2
3
4
5
abc
bca
cab
dog
god
x
排序后的字符串是分组键
groups(key → 单词)
{ }
键相同的单词归为一组
1 / 8
查看 C++ 代码

延伸阅读

  • “为每个元素找一个规范键”是哈希分组的通用套路;键必须满足:同组元素键相同,不同组键不同。
  • 如果只需要判断两个单词是否互为异位词,比较排序后的字符串或计数数组即可。