如何对字符串数组中的变位词进行分组?求最优实现思路
变位词分组的最优实现方案
嘿,针对你提出的变位词分组需求,结合你的场景(10个左右的字符串),我来给你梳理下最优实现思路,顺便聊聊二维数组的可行性~
一、最优思路:用哈希表(HashMap)做分组核心
变位词的本质是字符组成完全一致(如果需要忽略大小写的话,统一处理即可),所以我们可以给每个字符串生成一个「特征键」——所有变位词的特征键会完全相同,这样用哈希表就能轻松把它们归为一组,比挨个调用变位词判断方法高效太多。
常用的特征键生成方式有两种,都很适合你的场景:
- 排序字符法:把字符串转成统一大小写(比如全小写),再对字符排序。比如
Dog、God、dGO转小写后排序都是dgo,自然会被分到同一组。这种方法代码最简单,适合短字符串。 - 字符计数法:统计每个字符出现的次数,转成固定格式的字符串(比如
a:0,b:0...d:1,g:1,o:1)。这种方法适合长字符串,排序的开销会更小,但你的场景短字符串用排序法足够。
二、具体实现步骤(附Java代码示例)
既然你已经有判断变位词的方法,但用哈希表的话其实不需要单独调用它——直接通过特征键分组更高效。以Java为例,步骤如下:
- 初始化一个
HashMap<String, List<String>>:键是特征键,值是对应分组的字符串列表。 - 遍历每个输入字符串:
- 先统一大小写(比如
str.toLowerCase()),处理大小写不敏感的情况; - 生成特征键:把字符串转成字符数组,排序后再转回字符串;
- 检查哈希表中是否有这个键:有就把当前字符串加到对应列表,没有就新建列表存入。
- 先统一大小写(比如
- 最后把哈希表的所有值取出来,就是分组好的结果,想要转成二维数组也很方便。
可运行的代码片段
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)); } } }
运行这段代码,输出的结果和你给出的示例完全一致。
三、关于二维数组的可行性
二维数组是可行的,但绝对不是最优选择。如果用二维数组实现,你得这么做:
- 要么初始化一个固定大小的二维数组(但你不知道会有多少组),要么用动态列表再转成二维数组;
- 遍历每个字符串时,要和已有的每个分组里的字符串逐一比较(调用你的变位词判断方法),找到匹配的组就加进去,找不到就新建组;
- 这种方法的时间复杂度是O(n²)(n是字符串数量),10个字符串虽然性能没问题,但代码会繁琐很多,而且如果以后字符串数量增加,效率会直线下降。
而哈希表的方法时间复杂度是O(n*k log k)(k是字符串平均长度),对于你的场景来说几乎是线性的,代码也简洁易维护。
总结
- 首选方案:哈希表+特征键,代码简单、效率高,既适合当前的小数据量,也能应对未来的扩展;
- 二维数组可行,但仅适合极小数据量,代码冗余,不推荐作为首选。
内容的提问来源于stack exchange,提问作者noobJavaCoder
相关产品推荐
相关产品推荐

