# LeetCode 49. 字母异位词分组
## 题目
给你一个字符串数组,请你将**字母异位词**组合在一起。可以按任意顺序返回结果列表。
**字母异位词**:由相同的字母组成,只是排列顺序不同的字符串。
**示例:**
输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["eat","tea","ate"], ["tan","nat"], ["bat"]]
**提示:**
- 1 ≤ strs.length ≤ 10^4
- 0 < strs[i].length ≤ 100
---
## 一、思路
**核心规律**:字母异位词排序后的字符串相同
- `"eat"` → 排序 → `"aet"`
- `"tea"` → 排序 → `"aet"`
- `"ate"` → 排序 → `"aet"`
**算法步骤**:
1. 创建 `Map<String, List<String>>`
2. 遍历每个字符串,排序后作为 key
3. 将原字符串放入 key 对应的 list 中
4. 返回 map 中所有 value
---
## 二、举例演示
输入:`["eat", "tea", "tan", "ate", "nat", "bat"]`
过程:"eat" → "aet" → {"aet": ["eat"]}
"tea" → "aet" → {"aet": ["eat","tea"]}
"tan" → "ant" → {"aet":["eat","tea"], "ant":["tan"]}
"ate" → "aet" → {"aet":["eat","tea","ate"], "ant":["tan"]}
"nat" → "ant" → {"aet":[...], "ant":["tan","nat"]}
"bat" → "abt" → {"aet":[...], "ant":[...], "abt":["bat"]}
输出:`[["eat","tea","ate"], ["tan","nat"], ["bat"]]`
---
## 三、核心代码
class Solution { public List<List<String>> groupAnagrams(String[] strs) { // 创建哈希表,键为排序后的字符串,值为异位词列表 Map<String, List<String>> map = new HashMap<>(); // 遍历每个字符串 for (String s : strs) { // 将字符串转为字符数组,以便排序 char[] chars = s.toCharArray(); // 对字符数组排序,异位词排序后结果相同 Arrays.sort(chars); // 将排序后的字符数组转回字符串,作为哈希表的键 String key = new String(chars); // 如果当前键不存在,则先创建一个空列表存入 // 等价写法:if (!map.containsKey(key)) map.put(key, new ArrayList<>()); map.putIfAbsent(key, new ArrayList<>()); // 获取该键对应的列表,并将原始字符串加入 map.get(key).add(s); } // 返回哈希表中所有值(即分组后的列表集合) return new ArrayList<>(map.values()); } }## 四、方法注解
| 方法 | 所属类 | 作用 |
toCharArray() | String | 将字符串转换为字符数组 |
Arrays.sort() | Arrays | 对数组排序(升序) |
putIfAbsent() | Map | 如果 key 不存在则存入,否则不做操作 |
get() | Map | 根据 key 获取 value |
add() | List | 向列表中添加元素 |
values() | Map | 返回所有 value 的集合 |
new ArrayList<>(Collection) | ArrayList | 用集合创建新的 ArrayList |
put() | Map | 存入键值对 |
containsKey() | Map | 判断 key 是否存在 |
keySet() | Map | 获取所有 key 的集合 |
remove() | Map | 删除指定 key |
size() | Map | 返回键值对数量 |