【LeetCode热题100】打卡第18天:字母异位词分组

字母异位词分组

⛅前言

大家好,我是知识汲取者,欢迎来到我的LeetCode热题100刷题专栏!

精选 100 道力扣(LeetCode)上最热门的题目,适合初识算法与数据结构的新手和想要在短时间内高效提升的人,熟练掌握这 100 道题,你就已经具备了在代码世界通行的基本能力。在此专栏中,我们将会涵盖各种类型的算法题目,包括但不限于数组、链表、树、字典树、图、排序、搜索、动态规划等等,并会提供详细的解题思路以及Java代码实现。如果你也想刷题,不断提升自己,就请加入我们吧!QQ群号:827302436。我们共同监督打卡,一起学习,一起进步。

博客主页:知识汲取者的博客

LeetCode热题100专栏:LeetCode热题100

Gitee地址:知识汲取者 (aghp) - Gitee.com

Github地址:Chinafrfq · GitHub

题目来源:LeetCode 热题 100 - 学习计划 - 力扣(LeetCode)全球极客挚爱的技术成长平台

PS:作者水平有限,如有错误或描述不当的地方,恳请及时告诉作者,作者将不胜感激

题目

原题链接:49. 字母异位词分组

【LeetCode热题100】打卡第18天:字母异位词分组_第1张图片

题解

  • 解法一:暴力

    暴力的思路很简单,先遍历一遍strs,得到所有不同类型的字母异位词的种类,将他们存储到一个map集合中,key就是这个异位词,然后value标记位索引(从0开始),方便后面list集合定位到不同的分组。唯一需要注意的就是要对 list 进行初始化,否则会出现NPE!一遍过的感觉就是爽(●ˇ∀ˇ●)

    这里给对示例一进行代码运行过程的模拟:

    【LeetCode热题100】打卡第18天:字母异位词分组_第2张图片

    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;
        }
    }
    

    复杂度分析:

    • 时间复杂度: O ( n ∗ m ∗ l o g m ) O(n*m*logm) O(nmlogm),一遍for循环换的时间复杂度是 n n n,然后排序的时间复杂度是 m ∗ l o g m m*logm mlogm
    • 空间复杂度: O ( n ∗ m ) O(n*m) O(nm)

    其中 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());
        }
    }
    

    复杂度分析:

    • 时间复杂度: O ( n ∗ m ∗ l o g m ) O(n*m*logm) O(nmlogm),一遍for循环换的时间复杂度是 n n n,然后排序的时间复杂度是 m ∗ l o g m m*logm mlogm
    • 空间复杂度: O ( n ∗ m ) O(n*m) O(nm)

    其中 n n n 为字符串数组的长度, m m m位字符串的最大长度

你可能感兴趣的:(#,LeetCode热题100,Programming,practice,leetcode,java,链表)