LeetCode 字母异位词分组

官方题解详细解析

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

字母异位词 是由重新排列源单词的所有字母得到的一个新单词。

示例 1:

输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]

示例 2:

输入: strs = [""]
输出: [[""]]

示例 3:

输入: strs = ["a"]
输出: [["a"]]

提示:

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

题解

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        Map<String, List<String>> map = new HashMap<String, List<String>>();
        for (String str : strs) {
            char[] array = str.toCharArray();
            Arrays.sort(array);
            String key = new String(array);
            List<String> list = map.getOrDefault(key, new ArrayList<String>());
            list.add(str);
            map.put(key, list);
        }
        return new ArrayList<List<String>>(map.values());
    }
}

作者:力扣官方题解
链接:https://leetcode.cn/problems/group-anagrams/solutions/520469/zi-mu-yi-wei-ci-fen-zu-by-leetcode-solut-gyoc/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

解析

代码逐行解释

```java
class Solution {
```
- 定义了一个名为 `Solution` 的类。

---

```java
    public List<List<String>> groupAnagrams(String[] strs) {
```
- 定义了一个公共方法 `groupAnagrams`,它接收一个字符串数组 `strs` 作为参数,并返回一个 `List<List<String>>` 类型的结果。
- 返回值是一个列表,其中每个元素是一个字符串列表,表示一组变位词。

---

```java
        Map<String, List<String>> map = new HashMap<String, List<String>>();
```
- 创建一个 `HashMap`,键的类型是 `String`,值的类型是 `List<String>`。
- 这个 `map` 用于存储分组结果,键是排序后的字符串,值是对应的原始字符串列表。

---

```java
        for (String str : strs) {
```
- 使用增强的 `for` 循环遍历输入数组 `strs`,每次取出一个字符串 `str`。

---

```java
            char[] array = str.toCharArray();
```
- 将当前字符串 `str` 转换为字符数组 `array`,以便进行排序。

---

```java
            Arrays.sort(array);
```
- 对字符数组 `array` 进行排序。排序后,所有变位词的字符数组会变成相同的顺序。

---

```java
            String key = new String(array);
```
- 将排序后的字符数组 `array` 转换回字符串 `key`。这个 `key` 将作为哈希表的键,用于标识一组变位词。

---

```java
            List<String> list = map.getOrDefault(key, new ArrayList<String>());
```
- 从 `map` 中获取与 `key` 对应的列表 `list`。如果 `key` 不存在,则使用 `new ArrayList<String>()` 创建一个新的空列表。
- `getOrDefault` 方法确保即使 `key` 不存在,也不会抛出异常,而是返回默认值。

---

```java
            list.add(str);
```
- 将当前字符串 `str` 添加到列表 `list` 中。

---

```java
            map.put(key, list);
```
- 将更新后的列表 `list` 重新放入 `map` 中,键为 `key`。
- 如果 `key` 已经存在,则会覆盖原有的值;如果不存在,则会新增一个键值对。

---

```java
        }
```
- 结束 `for` 循环。

---

```java
        return new ArrayList<List<String>>(map.values());
```
- 从 `map` 中提取所有的值(即所有分组后的列表),并将其转换为 `ArrayList<List<String>>` 类型返回。
- `map.values()` 返回一个包含所有值的集合,`new ArrayList<>()` 将其转换为列表。

---

```java
    }
```
- 结束 `groupAnagrams` 方法。

---

```java
}
```
- 结束 `Solution` 类。

---

代码总结
1. **核心思想**:
   - 通过将每个字符串排序后的结果作为唯一标识(键),将变位词分组。
   - 使用哈希表存储分组结果,键是排序后的字符串,值是对应的原始字符串列表。

2. **执行流程**:
   - 遍历输入数组,对每个字符串进行排序,生成键。
   - 将字符串添加到对应键的列表中。
   - 最终返回所有分组列表。

3. **复杂度分析**:
   - 时间复杂度:`O(n * k log k)`,其中 `n` 是字符串数量,`k` 是字符串最大长度。排序每个字符串需要 `O(k log k)` 时间。
   - 空间复杂度:`O(n * k)`,哈希表存储所有字符串的键和列表。

4. **适用场景**:
   - 适用于需要将变位词分组的场景,如字母异位词分组问题。

---

### **示例**
**输入**:
```java
String[] strs = {"eat", "tea", "tan", "ate", "nat", "bat"};
```

**执行过程**:
1. `"eat"` -> 排序 -> `"aet"` -> 添加到键 `"aet"` 的列表。
2. `"tea"` -> 排序 -> `"aet"` -> 添加到键 `"aet"` 的列表。
3. `"tan"` -> 排序 -> `"ant"` -> 添加到键 `"ant"` 的列表。
4. `"ate"` -> 排序 -> `"aet"` -> 添加到键 `"aet"` 的列表。
5. `"nat"` -> 排序 -> `"ant"` -> 添加到键 `"ant"` 的列表。
6. `"bat"` -> 排序 -> `"abt"` -> 添加到键 `"abt"` 的列表。

**输出**:
```java
[
  ["eat", "tea", "ate"],
  ["tan", "nat"],
  ["bat"]
]
```

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值