LeetCode49 字母异位词分组|HashMap 分组
·
LeetCode49 字母异位词分组|HashMap 分组,数组 toString 大坑
题目描述
给你一个字符串数组,请你将字母异位词组合在一起。可以按任意顺序返回结果列表。
字母异位词:字母组成完全一样,字符顺序不一样,例如
eat、tea、ate。
我的做题思考全过程
审题:要把字母一样、顺序不一样的字符串分到同一组。
我想到一个关键点:异位词把字符排序之后,得到的字符串完全一样。
解题思路:
- 使用 HashMap 做分组,key 存放排序后的字符串,value 存放一组原始字符串 List。
- 循环遍历字符串数组,取出每一个字符串 s。
- String 不能直接排序,转为 char [] 字符数组,调用 Arrays.sort 对数组排序。
- 将排完序的字符数组转字符串,作为 map 的 key。
- 判断 map 有没有这个 key:没有就新建一个 ArrayList 放进去;有就直接拿到已有的 List。
- 把原始字符串 s 添加进 list。
- 全部遍历结束,map 的所有 value 就是分组完成的数据,转为 List 返回。
做题踩坑记录(真实写代码遇到的错误)
- ❗char 数组不能直接使用
arr.toString()
我写代码写成String key = arr.toString;,直接编译报错;改成arr.toString()运行也不对。
char 数组调用 toString 得到的是内存地址
[C@xxxx,不是字符串内容。
✅正确写法:new String(arr),把 char 数组转为真正的字符串。
- 不能
new List<List<String>>[]
Java 不支持直接 new 带泛型的数组,一开始想直接创建二维 List 数组存储分组,编译报错,改用 HashMap 分组才解决。 - map.values () 不能直接 return
map.values()返回的是 Collection 集合,和题目需要返回的List<List<String>>类型不匹配。
✅需要包装:new ArrayList<>(map.values())。 - 空指针风险
调用map.get(key).add(s)之前,必须containsKey判断 key 是否存在。
如果 key 不存在,get 拿到 null,调用 add 直接抛出空指针异常。 - for 循环两种写法
可以用普通 for 下标循环,也可以增强 for 循环。本题我使用下标 for 循环,手动拿strs[i]。
AC 完整代码
import java.util.*;
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
Map<String,List<String>> map=new HashMap<>();
for(int i = 0;i<strs.length;i++){
String s=strs[i];
char[] arr=s.toCharArray();
Arrays.sort(arr);
String key=new String(arr);
if(!map.containsKey(key)){
map.put(key,new ArrayList<>());
}
map.get(key).add(s);
}
return new ArrayList<>(map.values());
}
}
- 时间复杂度:(O(n*k \log k)) n 是字符串数量,k 字符串最大长度
- 空间复杂度:(O(nk))
复习 HashMap 刷题常用 API
表格
| 方法 | 作用 |
|---|---|
| containsKey(key) | 判断 map 是否存在该 key,返回 boolean |
| put(key,value) | 存入键值对,key 重复会覆盖旧 value |
| get(key) | 根据 key 获取 value,不存在返回 null |
| map.values() | 获取 map 全部的 value 集合 |
| map.keySet() | 获取全部 key 集合 |
总结
- char [] 转字符串:
new String(char数组),千万不要直接数组.toString ()。 - 分组类题目优先想到 HashMap,用一个特征值当 key 做归类。
- get 之前优先 containsKey 判断,规避空指针。
- Collection 不能直接当 List 返回,用
new ArrayList<>(collection)做转换。
更多推荐


所有评论(0)