力扣最热100题之字母异位词分组

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次。
示例 1:
输入: strs = [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”]
输出: [[“bat”],[“nat”,“tan”],[“ate”,“eat”,“tea”]]
示例 2:
输入: strs = [“”]
输出: [[“”]]

思路:注意,看到这种分组类问题,一定要想到数据结构map,因为map可以很好的完成我们要进行类别统计的任务,也可以根据k分类不同的value。
其实,很直观的解法是暴力解法,我们可以遍历每一个字符串数组中的字符串,然后用int数组统计里面字母以及字母的个数。将这个数组和list中的每一个数组比较,如果相等,就将其存入到本次相比的列表中,如果不等就继续循环,如果一直到循环结束还没找到相等的,那就说明目前列表中不存在该字符串的字母异位词,就将该字符串自己作为一个列表存入到大列表中。

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        
        if(strs.length == 0){
            return new ArrayList<List<String>>();
        }

        if(strs.length == 1){
            ArrayList<String> l = new ArrayList<>();
            l.add(strs[0]);
            List<List<String>> l1 = new ArrayList<List<String>>();
            l1.add(l);
            return l1;
        }

        List<List<String>> list = new ArrayList<List<String>>();

        boolean[] flag = new boolean[strs.length];

        for(int i = 0; i < strs.length && flag[i] == false; i++){
        
            if(list.size() == 0){
                // List<String> li = new ArrayList<String>(strs[0]);
                
                ArrayList<String> l = new ArrayList<>();
                l.add(strs[0]);
                // List<List<String>> l1 = new ArrayList<List<String>>();
                list.add(l);
            }else{
                int j = 0;
                for(j = 0; j < list.size(); j++){
                    int[] m = new int[26];
                    int[] n = new int[26];

                    String s = list.get(j).get(0);
                    String s1 = strs[i];

                    for(int k = 0; k < s.length(); k++){
                        m[s.charAt(k) - 'a'] += 1;
                    }

                    for(int k = 0; k < s1.length(); k++){
                        n[s1.charAt(k) - 'a'] += 1;
                    }

                    if(Arrays.equals(m,n)){
                         list.get(j).add(s1);
                         break;
                    }
                }

                if(j == list.size()){

                    // list.add(new ArrayList<>(strs[i]));

                    ArrayList<String> l3 = new ArrayList<>();
                    l3.add(strs[i]);
                // List<List<String>> l1 = new ArrayList<List<String>>();
                    list.add(l3);
                }
            }
        }

        return list;
    }
}

但是,这种暴力解法复杂度极高,我们应该想办法优化解法。下面就介绍进一步使用map数据结构的解法。
字母异位词也就是两串字符串除了顺序其它都一样,并且每个字母只用一次,这个信息很重要。有了这个信息,我们就可以认为,每个字符串排序后是可以作为评判是否是异位词的标准的。因此我们可以将每个字符串都取出来,然后转化为字符数组,对字符数组内元素进行排序,然后用排好序的字符数组形成的字符串作为标识,寻找和它一样的字符串,这两个字符串就是字母异位词。显然,这就需要map数组,将排好序的字符数组形成的字符串作为标识key,后面value值是一个列表,存放和这个标识相同的所有字母异位词的列表。

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        Map<String, ArrayList<String>> map = new HashMap<>();
        for (String str : strs) {
            char[] chars = str.toCharArray();
            Arrays.sort(chars);
            String key = new String(chars);
            if (!map.containsKey(key)) {
                map.put(key, new ArrayList<>());
            }
            map.get(key).add(str);
        }
        return new ArrayList<>(map.values());
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值