中等LeetCode 49动画补充中引导学习
字母异位词分组
哈希表:按特征分组
给每个字符串算一个"规范特征"(把字母排序后的结果),特征相同的必然互为异位词——用哈希表按特征分组。
时间复杂度 O(n · k log k)(k 为字符串长度)空间复杂度 O(n · k)
题单:面试热题
题目描述
给定一个字符串数组,把其中互为字母异位词的字符串分到同一组。字母异位词指字母种类和数量完全相同、只是排列顺序不同的两个字符串,返回所有分组。
学习目标
能解释"排序后的字符串"为什么可以作为异位词的特征,并用哈希表完成分组。
已完成 0 / 6 阶段
诊断
先问:怎么判断两个词是异位词
两个字符串互为异位词,本质上要满足什么条件?只看长度或字母集合够不够?
建议先完成当前阶段(提示 / 检查 / 自评),再进入下一步;也可以直接跳过。
解题思路
核心思想
给每个字符串算一个"规范特征"(把字母排序后的结果),特征相同的必然互为异位词——用哈希表按特征分组。
为什么需要它
直接两两比较判断异位词,每次都要 O(k)、总共 O(n²k)。如果能给每个词算一个"指纹",等价的词指纹相同,分组就变成一次哈希归并。
第一反应:直觉方案
对每个词,和已经分好的每一组逐一比较,判断是否互为异位词——能过,但全是重复比较。
关键洞察
关键洞察是"异位词 ⇔ 排序后相同":排序把"顺序"这个噪音去掉,只留下"字母构成"这个本质特征。这个"构造等价类钥匙"的思路可以推广到很多题:任何"等价关系"问题都可以想办法造一把钥匙(排序、计数、编码都行)。
时间复杂度 O(n · k log k)(k 为字符串长度)空间复杂度 O(n · k)
易错点
- 特征用排序结果(JS 的 [...s].sort().join(""),Python 的 sorted),别用集合——"aab" 和 "ab" 的字母集合相同但数量不同
- JS 排序前要先拆成数组(字符串没有 sort)
- 不能直接用原字符串做 key,顺序也是信息
参考代码
参考代码
1function groupAnagrams(strs) {
2 const groups = new Map();
3 for (const s of strs) {
4 const key = [...s].sort().join(''); // 排序后的字符串作为特征
5 if (!groups.has(key)) groups.set(key, []);
6 groups.get(key).push(s);
7 }
8 return [...groups.values()];
9}
逐步演示
这道题目前是索引版:题面、解题思路与双语言代码已是完整内容; 逐步动画会按计划补充。