LeetCode 第49题:字母异位词分组
题目描述
给你一个字符串数组 strs,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的所有字母得到的一个新单词。
难度
中等
题目链接
示例
示例 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]仅包含小写字母- 所有单词都由小写字母组成
解题思路
排序 + 哈希表
这道题的核心思想是:字母异位词排序后得到相同的字符串。我们可以将排序后的字符串作为哈希表的键,原字符串列表作为值。
关键点:
- 对每个字符串进行字符排序
- 使用哈希表存储排序后的字符串到原字符串列表的映射
- 最后将哈希表的所有值转换为结果列表
- 注意处理空字符串的特殊情况
具体步骤:
- 创建哈希表存储分组结果
- 遍历字符串数组,对每个字符串排序
- 将原字符串添加到对应的分组中
- 返回所有分组的列表
图解思路
算法步骤分析表
| 步骤 | 操作 | 状态 | 说明 |
|---|---|---|---|
| 初始 | - | ["eat","tea","tan"] | 原始数组 |
| 排序 | 字符排序 | ["aet","aet","ant"] | 每个字符串排序 |
| 分组 | 哈希存储 | {"aet":["eat","tea"], "ant":["tan"]} | 按排序结果分组 |
| 结果 | 转换列表 | [["eat","tea"],["tan"]] | 提取分组结果 |
状态/情况分析表
| 情况 | 输入 | 输出 | 说明 |
|---|---|---|---|
| 基本情况 | ["eat","tea","tan"] | [["eat","tea"],["tan"]] | 标准分组 |
| 空字符串 | [""] | [[""]] | 特殊情况 |
| 单字符 | ["a"] | [["a"]] | 单个字符 |
代码实现
C# 实现
public class Solution {
public IList<IList<string>> GroupAnagrams(string[] strs) {
var groups = new Dictionary<string, IList<string>>();
foreach (string s in strs) {
// 将字符串排序
char[] chars = s.ToCharArray();
Array.Sort(chars);
string key = new string(chars);
// 添加到对应的分组
if (!groups.ContainsKey(key)) {
groups[key] = new List<string>();
}
groups[key].Add(s);
}
// 返回所有分组
return groups.Values.ToList();
}
}
执行结果
- 执行用时:168 ms
- 内存消耗:48.2 MB
代码亮点
- 🎯 使用排序+哈希表的经典解法
- 💡 利用字符串排序作为分组依据
- 🔍 优化字符串处理过程
- 🎨 代码结构简洁明了
常见错误分析
- 🚫 忘记处理空字符串
- 🚫 字符串排序方法使用错误
- 🚫 哈希表键的设计不当
- 🚫 返回结果格式错误
解法对比
| 解法 | 时间复杂度 | 空间复杂度 | 优点 | 缺点 |
|---|---|---|---|---|
| 排序+哈希表 | O(nklogk) | O(nk) | 直观易懂 | 排序耗时 |
| 计数+哈希表 | O(nk) | O(nk) | 性能更好 | 实现复杂 |
| 质数乘积 | O(nk) | O(n) | 空间优化 | 可能溢出 |
相关题目
- 有效的字母异位词 - 简单
- 找到字符串中所有字母异位词 - 中等
- 字母异位词分组的数量 - 中等