大家好,我是知识汲取者,欢迎来到我的LeetCode热题100刷题专栏!
精选 100 道力扣(LeetCode)上最热门的题目,适合初识算法与数据结构的新手和想要在短时间内高效提升的人,熟练掌握这 100 道题,你就已经具备了在代码世界通行的基本能力。在此专栏中,我们将会涵盖各种类型的算法题目,包括但不限于数组、链表、树、字典树、图、排序、搜索、动态规划等等,并会提供详细的解题思路以及Java代码实现。如果你也想刷题,不断提升自己,就请加入我们吧!QQ群号:827302436。我们共同监督打卡,一起学习,一起进步。
博客主页:知识汲取者的博客
LeetCode热题100专栏:LeetCode热题100
Gitee地址:知识汲取者 (aghp) - Gitee.com
Github地址:Chinafrfq · GitHub
题目来源:LeetCode 热题 100 - 学习计划 - 力扣(LeetCode)全球极客挚爱的技术成长平台
PS:作者水平有限,如有错误或描述不当的地方,恳请及时告诉作者,作者将不胜感激
原题链接:49. 字母异位词分组
解法一:暴力
暴力的思路很简单,先遍历一遍strs,得到所有不同类型的字母异位词的种类,将他们存储到一个map集合中,key就是这个异位词,然后value标记位索引(从0开始),方便后面list集合定位到不同的分组。唯一需要注意的就是要对 list 进行初始化,否则会出现NPE!一遍过的感觉就是爽(●ˇ∀ˇ●)
这里给对示例一进行代码运行过程的模拟:
import java.util.*;
/**
* @author ghp
* @title 字母异位词分组
*/
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
List<List<String>> ans = new ArrayList<>(10);
// 获取strs中所有不同类型字母异位词
Map<String, Integer> map = new HashMap<>(16);
int i = 0;
for (String str : strs) {
char[] chars = str.toCharArray();
Arrays.sort(chars);
String tempStr = new String(chars);
// 判断当前字符串是否重复,只有不重复在加入map中
if (!map.containsKey(tempStr)){
map.put(tempStr, i++);
// 初始化list,防止后面出现NPE
List<String> list = new ArrayList<>(10);
ans.add(list);
}
}
// 遍历strs,将不同字母异味词进行一个归类
for (int j = 0; j < strs.length; j++) {
char[] chars = strs[j].toCharArray();
Arrays.sort(chars);
String key = new String(chars);
ans.get(map.get(key)).add(strs[j]);
}
return ans;
}
}
复杂度分析:
其中 n n n 为字符串数组的长度, m m m位字符串的最大长度
解法二:排序(这个是LeetCode官方提供的)
可以看到LeetCode官方提供的代码,和我写思路是类似的的。都是先对字符串进行排序,然后通过map的key不重复的特性来记录不同异位字母。相比较,官方代码最大的亮点就是使用了
getOrDefault
方法,该方法是Java8新增的,相较于传统的get
方法,不会发生NPE问题,所以不要像我之前写的那样,还要去初始化List,这样就能够很好的将两个for循环合并成一个,这样虽然时间复杂度没有降低,但是一定程度上也降低了时间损耗(经测试解法一耗时8ms,解法二耗时5ms)
import java.util.*;
/**
* @author ghp
* @title 字母异位词分组
*/
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
Map<String, List<String>> map = new HashMap<>();
// 遍历strs,对异位字母进行分组
for (String str : strs) {
// 对字符串按照字母顺序进行排序(自然顺序)
char[] array = str.toCharArray();
Arrays.sort(array);
String key = new String(array);
// 获取对应key的value值,key不存在就返回默认值(也就是一个ArrayList对象)
List<String> list = map.getOrDefault(key, new ArrayList<>());
list.add(str);
map.put(key, list);
}
return new ArrayList<>(map.values());
}
}
复杂度分析:
其中 n n n 为字符串数组的长度, m m m位字符串的最大长度