49. 字母异位词分组

题目

给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。

示例:

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

说明:

所有输入均为小写字母。
不考虑答案输出的顺序。

HashMap

如何让字符串找到它对应的分组?很显然要用HashMap。最后map.values()可返回所有value的集合,不过要注意该方法返回的是Collection类型。

唯一的问题在于使用什么作为key,这个key要唯一地对应到一个分组。

排序后的字符串作为key
将排好序的字符串作为key。那么如何给一个String对象排好序呢?可以使用String的toCharArray()方法先得到对应的字符数组,对这个数组进行排序,最后将排好序的字符数组重新转化为String对象即可。

  public List<List<String>> groupAnagrams(String[] strs) {
        Map<String,List<String>> map=new HashMap<>();
        for(int i=0;i<strs.length;++i){
            char[] array=strs[i].toCharArray();
            Arrays.sort(array);
            String key=new String(array);
            //getOrDefault(key,defaultValue):返回key对应的value,若不存在该键值对则返回defaultValue
            List<String> list=map.getOrDefault(key,new ArrayList<String>());
            list.add(strs[i]);
            map.put(key,list);
        }
        return new ArrayList<List<String>>(map.values());
  }

包含计数信息的字符串作为key
对每个字符串计数得到该字符串的计数数组,对于计数数组相同的字符串,就互为异位词。

因为数组类型没有重写 hashcode() 和 equals() 方法,因此不能直接作为 HashMap 的 Key 进行聚合,那么我们就把这个数组手动编码变成字符串就行了。
比如将 [b,a,a,a,b,c] 编码成 a3b2c1,使用编码后的字符串作为HashMap的Key 。

 public List<List<String>> groupAnagrams(String[] strs) {
        Map<String,List<String>> map=new HashMap<>();
        for(String str:strs){
            int[] cnt=new int[26];
            for(int i=0;i<str.length();++i){
                cnt[str.charAt(i)-'a']++;
            }
            StringBuilder sb=new StringBuilder("");
            for(int i=0;i<26;++i){
                if(cnt[i]>0) sb.append(""+('a'+i)+cnt[i]);
            }
            String key=new String(sb);
            List<String> list=map.getOrDefault(key,new ArrayList<String>());
            list.add(str);
            map.put(key,list);
        }
        return new ArrayList<List<String>>(map.values());
 }

leetcode原题:49.字母异位词分组
参考:看我一句话 AC 字母异位词分组!

posted @ 2021-04-17 22:02  归鸿唱晚  阅读(76)  评论(0编辑  收藏  举报