You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对字符串数组中的变位词进行分组?求最优实现思路

变位词分组的最优实现方案

嘿,针对你提出的变位词分组需求,结合你的场景(10个左右的字符串),我来给你梳理下最优实现思路,顺便聊聊二维数组的可行性~

一、最优思路:用哈希表(HashMap)做分组核心

变位词的本质是字符组成完全一致(如果需要忽略大小写的话,统一处理即可),所以我们可以给每个字符串生成一个「特征键」——所有变位词的特征键会完全相同,这样用哈希表就能轻松把它们归为一组,比挨个调用变位词判断方法高效太多。

常用的特征键生成方式有两种,都很适合你的场景:

  • 排序字符法:把字符串转成统一大小写(比如全小写),再对字符排序。比如Dog、God、dGO转小写后排序都是dgo,自然会被分到同一组。这种方法代码最简单,适合短字符串。
  • 字符计数法:统计每个字符出现的次数,转成固定格式的字符串(比如a:0,b:0...d:1,g:1,o:1)。这种方法适合长字符串,排序的开销会更小,但你的场景短字符串用排序法足够。

二、具体实现步骤(附Java代码示例)

既然你已经有判断变位词的方法,但用哈希表的话其实不需要单独调用它——直接通过特征键分组更高效。以Java为例,步骤如下:

  1. 初始化一个HashMap<String, List<String>>:键是特征键,值是对应分组的字符串列表。
  2. 遍历每个输入字符串:
    • 先统一大小写(比如str.toLowerCase()),处理大小写不敏感的情况;
    • 生成特征键:把字符串转成字符数组,排序后再转回字符串;
    • 检查哈希表中是否有这个键:有就把当前字符串加到对应列表,没有就新建列表存入。
  3. 最后把哈希表的所有值取出来,就是分组好的结果,想要转成二维数组也很方便。

可运行的代码片段

import java.util.*;

public class AnagramGrouping {
    public static List<List<String>> groupAnagrams(String[] strs) {
        Map<String, List<String>> anagramMap = new HashMap<>();
        
        for (String s : strs) {
            // 统一转小写,处理大小写差异
            String lowerS = s.toLowerCase();
            // 生成排序后的特征键
            char[] chars = lowerS.toCharArray();
            Arrays.sort(chars);
            String key = new String(chars);
            
            // 加入对应分组(computeIfAbsent简化了判断逻辑)
            anagramMap.computeIfAbsent(key, k -> new ArrayList<>()).add(s);
        }
        
        // 如果需要转成二维数组,用下面这行:
        // String[][] result = anagramMap.values().stream().map(l -> l.toArray(new String[0])).toArray(String[][]::new);
        
        return new ArrayList<>(anagramMap.values());
    }

    public static void main(String[] args) {
        String[] input = {"Dog", "Bread", "Africa", "God", "Dreab", "dGO", "Treat", "dabre", "trate", "China"};
        List<List<String>> groups = groupAnagrams(input);
        
        // 打印分组结果
        int groupIdx = 1;
        for (List<String> group : groups) {
            System.out.printf("组%d: %s%n", groupIdx++, String.join(", ", group));
        }
    }
}

运行这段代码,输出的结果和你给出的示例完全一致。

三、关于二维数组的可行性

二维数组是可行的,但绝对不是最优选择。如果用二维数组实现,你得这么做:

  1. 要么初始化一个固定大小的二维数组(但你不知道会有多少组),要么用动态列表再转成二维数组;
  2. 遍历每个字符串时,要和已有的每个分组里的字符串逐一比较(调用你的变位词判断方法),找到匹配的组就加进去,找不到就新建组;
  3. 这种方法的时间复杂度是O(n²)(n是字符串数量),10个字符串虽然性能没问题,但代码会繁琐很多,而且如果以后字符串数量增加,效率会直线下降。

而哈希表的方法时间复杂度是O(n*k log k)(k是字符串平均长度),对于你的场景来说几乎是线性的,代码也简洁易维护。

总结

  • 首选方案:哈希表+特征键,代码简单、效率高,既适合当前的小数据量,也能应对未来的扩展;
  • 二维数组可行,但仅适合极小数据量,代码冗余,不推荐作为首选。

内容的提问来源于stack exchange,提问作者noobJavaCoder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:11:32