力扣题49字母异位词分组

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。

字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母都恰好只用一次。

示例 1:

输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
示例 2:

输入: strs = [""]
输出: [[""]]
示例 3:

输入: strs = ["a"]
输出: [["a"]]

1.自己的解法:双重循环,比较复杂。

class Solution {
    public List> groupAnagrams(String[] strs) {
        List> list = new ArrayList<>();
        boolean[] isAdd = new boolean[strs.length];//用一个辅助数组来表示这个元素是否已经被添加进了list,避免重复计算

        for(int i = 0;i < strs.length;i++){//从第一个元素开始遍历
            List subList = new ArrayList<>();
            if(isAdd[i]){//如果当前元素被遍历过,直接跳过
                continue;
            }else{//当前元素未被遍历过
                for(int j = i;j < strs.length;j++){//判断后面的元素是不是字母异位词
                    if(isAdd[j]){//已经被添加过,说明不属于当前的subList
                        continue;
                    }

                    if(hasSameCharacter(strs[i],strs[j])){//如果两个元素的字符完全相等
                        subList.add(strs[j]);//加入subList
                        isAdd[j] = true;//设置为被添加过
                    }
                }
                list.add(subList);//加入当前subList
            }
        }
        return list;
    }

    //比较两个字符串的字符是都一样
    public boolean hasSameCharacter(String str1,String str2){
        if(str1.length() != str2.length()){
            return false;
        }else{
            char[] char1 = str1.toCharArray();
            Arrays.sort(char1);
            char[] char2 = str2.toCharArray();
            Arrays.sort(char2);
            for(int i = 0;i < char1.length;i++){
                if(char1[i] != char2[i]){
                    return false;
                }
            }
        }
        return true;
    }
}

2.答案解法:

        两个字符串互为字母异位词,当且仅当两个字符串包含的字母相同。同一组字母异位词中的字符串具备相同点,可以使用相同点作为一组字母异位词的标志,使用哈希表存储每一组字母异位词,哈希表的键为一组字母异位词的标志,哈希表的值为一组字母异位词列表。遍历每个字符串,对于每个字符串,得到该字符串所在的一组字母异位词的标志,将当前字符串加入该组字母异位词的列表中。遍历全部字符串之后,哈希表中的每个键值对即为一组字母异位词。

        ①排序。最推荐的方法。

class Solution {
    public List> groupAnagrams(String[] strs) {
        Map> map = new HashMap>();//哈希表
        for (String str : strs) {
            char[] array = str.toCharArray();//将当前的字符串转化为char数组
            Arrays.sort(array);//对char数组排序,作为key。因为字母异位词的排序后的char数组肯定是一样的
            String key = new String(array);
            List list = map.getOrDefault(key, new ArrayList());//如果这个key已经存在了,就使用存在的list,如果不存在,就新建一个list。
            list.add(str);//将当前元素加入到对应的list中
            map.put(key, list);//加入哈希表中
        }
        return new ArrayList>(map.values());//哈希表的每个value值组成的集合就是最后要求的列表
    }
}

        ②计数。

class Solution {
    public List> groupAnagrams(String[] strs) {
        Map> map = new HashMap>();
        for (String str : strs) {
            int[] counts = new int[26];
            int length = str.length();
            for (int i = 0; i < length; i++) {
                counts[str.charAt(i) - 'a']++;//计算每个字母出现的次数
            }
            // 将每个出现次数大于 0 的字母和出现次数按顺序拼接成字符串,作为哈希表的键
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < 26; i++) {
                if (counts[i] != 0) {
                    sb.append((char) ('a' + i));
                    sb.append(counts[i]);
                }
            }
            String key = sb.toString();
            List list = map.getOrDefault(key, new ArrayList());
            list.add(str);
            map.put(key, list);
        }
        return new ArrayList>(map.values());
    }
}

题源:力扣

你可能感兴趣的:(力扣,leetcode,算法)