Day2:LeeCode Hot2-字母异位词分组
大家好,今天开启 LeetCode Hot100 系列 的第二篇:字母异位词分组。
这道题是哈希表+字符串预处理的标杆题目,也是面试高频考点。
核心考察对「异位词统一标识」的思维,同时能延伸出基础解法与优化解法的对比,非常适合夯实算法基础。
一、题目描述
给你一个字符串数组 strs,请你将字母异位词组合在一起。可以按任意顺序返回结果列表。
字母异位词:由相同字母、相同数量重新排列形成的字符串,仅字符顺序不同。题目默认所有字符串仅包含小写英文字母。
示例:
输入:strs = ["eat","tea","tan","ate","nat","bat"]
输出:[["bat"],["nat","tan"],["ate","eat","tea"]]
题目核心要求:相同字符组成的字符串分为一组,无序输出各组结果即可。
解题核心思路
这道题的本质不是复杂的算法逻辑,而是如何给异位词设计唯一标识。
所有互为异位词的字符串,字符种类、字符数量完全一致,唯一区别是字符顺序。只要我们能让同一组异位词拥有完全相同的标识,就可以通过哈希表实现分组映射:
-
key:异位词的统一唯一标识
-
value:对应标识的所有异位词列表
行业内主流有两种标识生成方案:字符串排序法(入门易懂)、字符计数法(高效优化),下面分别详细拆解。
三、解法:排序 + 哈希表
1. 思路分析
任意一组异位词,将字符排序后,得到的字符串完全一致。例如 eat、tea、ate 排序后均为 aet。
基于这个特性,我们可以将排序后的字符串作为哈希表key,遍历原数组,将每个字符串归入对应key的列表中,最终取出哈希表所有value即为分组结果。
2. 完整代码实现(Java)
public List<List<String>> groupAnagrams(String[] strs) {
// 排序后字符串为key,异位词集合为value
Map<String, List<String>> map = new HashMap<>();
for (String str : strs) {
// 字符串转字符数组、排序、重新拼接,生成统一标识
char[] chars = str.toCharArray();
Arrays.sort(chars);
String key = new String(chars);
// 不存在则新建列表,存在则直接加入集合
map.computeIfAbsent(key, k -> new ArrayList<>()).add(str);
}
// 哈希表所有值即为分组结果
return new ArrayList<>(map.values());
}
3. 复杂度分析
-
时间复杂度:
O(n * k log k)。n为字符串数组长度,k为单个字符串的最大长度。每个字符串需要进行O(k log k)的排序操作。 -
空间复杂度:
O(n * k)。需要存储所有字符串的分组结果,哈希表占用额外空间。
4. 优缺点总结
优点:代码极简、逻辑清晰、无边界坑点,面试首选入门写法,容错率极高。
缺点:依赖排序操作,对于超长字符串,时间开销会明显增加。
四、高频易错点总结
1. 空字符串处理:两种解法均可天然兼容空字符串,空字符串排序、计数结果均唯一,无需额外判空。
2. 大小写问题:题目限定小写字母,若未限定,需先统一大小写再处理。
3. 结果顺序:题目不要求分组顺序、组内元素顺序,无需额外排序,避免冗余开销。
五、刷题总结
1.题型定位:哈希表映射 + 字符串预处理,是字符串分组类问题的模板题,同类问题可直接复用「统一唯一标识+哈希分组」的核心思想。
2. 答题策略:面试中优先写排序哈希解法,代码简洁、无bug风险;
3. 核心思想迁移:所有「特征相同、形式不同」的分组问题,都可以通过「提取统一特征作为key、哈希映射分组」解决,是算法中非常通用的解题套路。
浙公网安备 33010602011771号