uacs2024

导航

leetcode49. 字母异位词分组

49. 字母异位词分组

微信截图_20251202184022

法一:每个字符串先排序,再加入到HashMap。自己写的。

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        int n = strs.length;
        HashMap<String,List<String>> mapStr = new HashMap<>();
        for(int i = 0;i < n;++i){
            char[] charArray = strs[i].toCharArray();// 1. 将字符串转换为字符数组     
            Arrays.sort(charArray);// 2. 对字符数组进行排序
            String sortedStr = new String(charArray);// 3. 将排序后的字符数组转换回字符串
            if(!mapStr.containsKey(sortedStr)){
                List<String> strList = new ArrayList<>();
                strList.add(strs[i]);
                mapStr.put(sortedStr,strList);
            }else{
                mapStr.get(sortedStr).add(strs[i]);
            }
        }
        return new ArrayList<>(mapStr.values());
    }
}

法一优化:使用 getOrDefault()或 computeIfAbsent()简化代码

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        HashMap<String, List<String>> mapStr = new HashMap<>();
        
        for (String str : strs) {
            char[] charArray = str.toCharArray();
            Arrays.sort(charArray);
            String sortedStr = new String(charArray);
            
            // 使用 computeIfAbsent 简化代码
            mapStr.computeIfAbsent(sortedStr, k -> new ArrayList<>()).add(str);
        }
        
        return new ArrayList<>(mapStr.values());
    }
}

法一Stream

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        return new ArrayList<>(
            Arrays.stream(strs)
                  .collect(Collectors.groupingBy(s -> {
                      char[] sortedS = s.toCharArray();
                      Arrays.sort(sortedS);
                      return new String(sortedS);
                  }))
                  .values()
        );
    }
}

 

法二:考虑使用字符计数法避免排序

假设我们有以下几个字符串,来看看它们生成的 key

原始字符串字符计数数组(简化表示)生成的键 (key)
""(空字符串) 所有字母计数均为0 #0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
"a" a=1, 其余为0 #1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
"cab" a=1, b=1, c=1, 其余为0 #1#1#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
"eat" a=1, e=1, t=1, 其余为0 #1#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1#0#0#0#0#0#0
class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        Map<String, List<String>> map = new HashMap<>();
        
        for (String str : strs) {
            int[] count = new int[26];
            for (char c : str.toCharArray()) {
                count[c - 'a']++;
            }
            
            // 构建计数键,添加分隔符避免歧义[2](@ref)
            StringBuilder keyBuilder = new StringBuilder();
            for (int i = 0; i < 26; i++) {
                keyBuilder.append('#').append(count[i]);
            }
            String key = keyBuilder.toString();
            
            map.computeIfAbsent(key, k -> new ArrayList<>()).add(str);
        }
        
        return new ArrayList<>(map.values());
    }
}

 

法三:质数乘积法(数学方法)

为每个字母分配一个质数,通过质数乘积的唯一性作为键

可能溢出,需要处理大数情况

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        int[] primes = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 
                       31, 37, 41, 43, 47, 53, 59, 61, 67, 
                       71, 73, 79, 83, 89, 97, 101};
        
        Map<Long, List<String>> map = new HashMap<>();
        
        for (String str : strs) {
            long product = 1;
            for (char c : str.toCharArray()) {
                product *= primes[c - 'a'];
            }
            map.computeIfAbsent(product, k -> new ArrayList<>()).add(str);
        }
        
        return new ArrayList<>(map.values());
    }
}

 

posted on 2025-12-02 19:29  ᶜʸᵃⁿ  阅读(0)  评论(0)    收藏  举报