leetCode热门100题——2.字母异位词分组

文章目录

  • 题目描述
  • 分析
    • 示例 1
    • 示例 2
    • 示例 3
    • 提示
  • 方法一:先排序后哈希
    • 思路
    • 代码
    • 时间复杂度
  • 方法二:先计数后哈希
    • 思路
    • 代码
    • 时间复杂度

题目描述

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词是由重新排列源单词的所有字母得到的一个新单词。


分析

解题关键在于,如何使得不同的字母异位词有相同的key值,让字母异位词进入到同一个哈希桶中。


示例 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] 仅包含小写字母


方法一:先排序后哈希

思路

  1. 先将字符串转化为字符数组对其进行排序,那么字母异位词的哈希结果应当是相同的。
  2. 对排序后数组使用Arrays类的hashCode方法
    (简要描述一下hashCode方法:他与数组的长度、顺序都有关,最后返回一个int类型的值)

代码

//排序后哈希
class Solution1 {
    
    
    public List<List<String>> groupAnagrams(String[] strs) {
    
    
        HashMap<Integer, List<String>> map = new HashMap<>();
        List<List<String>> ans = new ArrayList<>();//用于保存答案

        for(String s : strs){
    
    
            Integer key = getHashKey(s);
            if(map.containsKey(key)){
    
    
                map.get(key).add(s);
            }else{
    
    
                List<String> list = new ArrayList<>();
                list.add(s);
                map.put(key, list);
            }
        }

		for (Integer key : map.keySet()){
    
    
            ans.add(map.get(key));
        }

        if (ans.isEmpty()){
    
    
            List<String> empty = new ArrayList<>();
            empty.add("");
            ans.add(empty);
        }

        return ans;
    }

    /**
     * 获取hash key
     * @param s 字符串
     * @return hash key
     */
    //这个哈希函数能保证有相同的字母就返回相同的哈希值
    public Integer getHashKey(String s) {
    
    
        char[] temp = s.toCharArray();
        Arrays.sort(temp);
        return Arrays.hashCode(temp);
    }
}

时间复杂度

O(Nklogk),k为字符串的长度。排序方法用时O(klogk),总共N个,大致为Nklogk。


方法二:先计数后哈希

思路

  1. 对于每个字符串对其每个字母的出现次数计数,那么字母异位词的计数结果应当是相同的。
  2. 利用计数结果进行哈希

代码

//计数后哈希
class Solution2 {
    
    
    public List<List<String>> groupAnagrams(String[] strs) {
    
    
        HashMap<Integer, List<String>> map = new HashMap<>();
        List<List<String>> ans = new ArrayList<>();//用于储存最终结果
        
        for(String s : strs){
    
    
            int[] count = new int[26];
            // 遍历当前字符串的每个字符
            for (char c : s.toCharArray()){
    
    
                int temp = c - 'a';
                // 对应索引的计数加1
                count[temp]++;
            }

            // 将计数数组转换为哈希码,作为哈希表的键
            int key = Arrays.hashCode(count);

            List<String> temp = map.getOrDefault(key,new ArrayList<String>());
            temp.add(s);
            map.put(key,temp);//put方法会自动替换旧值并返回
        }

        for (int key : map.keySet()){
    
    
            ans.add(map.get(key));
        }

        if (ans.isEmpty()){
    
    
            List<String> temp = new ArrayList<>();
            temp.add("");
            ans.add(temp);
        }
        
        return ans;
    }

}

	

时间复杂度

O(Nk),获取计数结果为O(k);总共有 N个字符串。


有问题欢迎讨论,侵权必改