题目

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

示例 1:

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

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

解释:

  • 在 strs 中没有字符串可以通过重新排列来形成 "bat"
  • 字符串 "nat""tan" 是字母异位词,因为它们可以重新排列以形成彼此。
  • 字符串 "ate""eat""tea" 是字母异位词,因为它们可以重新排列以形成彼此。

示例 2:

输入: strs = [""]

输出: [[""]]

示例 3:

输入: strs = ["a"]

输出: [["a"]]

提示:

  • 1 <= strs.length <= 104
  • 0 <= strs[i].length <= 100
  • strs[i] 仅包含小写字母

解答

完整代码

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        return new ArrayList<>(Arrays.stream(strs)
            .collect(Collectors.groupingBy(str -> {
                // 返回 str 排序后的结果。
                // 按排序后的结果来grouping by,算子类似于 sql 里的 group by。
                char[] array = str.toCharArray();
                Arrays.sort(array);
                return new String(array);
            })).values());
    }
}
// 紧凑写法
public List<List<String>> groupAnagrams(String[] strs) {
    Map<String, List<String>> map = new HashMap<>();
  
    for (String str : strs) {
        char[] chars = str.toCharArray();
        Arrays.sort(chars);
        String key = new String(chars);
      
        map.computeIfAbsent(key, k -> new ArrayList<>()).add(str);
    }
  
    return new ArrayList<>(map.values());
}
// 普通写法

解释

  1. tream处理流程

    Arrays.stream(strs)
    

    将输入数组转换为Stream,便于进行函数式操作。

  2. 核心分组逻辑

    .collect(Collectors.groupingBy(str -> {
        char[] array = str.toCharArray();
        Arrays.sort(array);
        return new String(array);
    }))
    

    关键思路:将每个字符串排序后作为分组的key

    • 字母异位词排序后得到相同的字符串
    • 例如:"eat" → "aet", "tea" → "aet"

    步骤分解

    1. str.toCharArray() - 将字符串转为字符数组
    2. Arrays.sort(array) - 对字符数组排序
    3. return new String(array) - 将排序后的字符数组转回字符串作为key
  3. 结果转换

    java

    .values()
    

    groupingBy返回的是 Map<String, List<String>>

    • Key: 排序后的字符串(如"aet")
    • Value: 原始字符串列表(如["eat", "tea", "ate"])

    .values()只提取Map中的值部分,即 Collection<List<String>>