导读:本期聚焦于小伙伴创作的《如何用Java高效实现变位词分组?无需排序的哈希映射方法详解》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何用Java高效实现变位词分组?无需排序的哈希映射方法详解》有用,将其分享出去将是对创作者最好的鼓励。

JAVA高效分组变位词:无需排序的哈希映射方法

在处理字符串分组相关问题时,变位词分组是一个常见的场景。变位词指的是由相同字母重排列形成的字符串,比如 "eat"、"tea"、"ate" 就属于同一组变位词。传统的解法通常会先对字符串排序,将排序后的结果作为哈希表的键来分组,但排序本身会带来 O(k log k) 的时间开销(k 是字符串长度)。今天介绍一种无需排序的哈希映射方法,通过统计字符出现次数生成唯一键,效率更高。

核心思路

变位词的本质是组成字符串的字符种类和每个字符的出现次数完全一致。我们可以统计每个字符串中每个字符的出现次数,然后根据计数结果生成一个唯一的字符串作为哈希表的键:

  • 遍历字符串的每个字符,统计 26 个小写字母的出现次数(如果是包含其他字符的场景可以扩展数组长度)
  • 将计数结果拼接成固定格式的字符串,比如字符 a 出现 1 次,字符 e 出现 1 次,字符 t 出现 1 次,就生成 "#1#0#0#0#1#0...#1#0..." 这样的键
  • 用这个键作为 HashMap 的 key,对应的 value 就是该组变位词组成的列表
  • 最终遍历 HashMap 的 value 集合,就是所有分组后的结果

完整代码实现

下面是基于上述思路的 Java 实现代码,假设输入字符串仅包含小写字母,如果是其他场景可以调整计数数组的长度和键的生成逻辑:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class AnagramGroup {
    public List<List<String>> groupAnagrams(String[] strs) {
        // 键是字符计数生成的唯一标识,值是该组变位词列表
        Map<String, List<String>> map = new HashMap<>();
        
        for (String str : strs) {
            // 统计26个小写字母的出现次数
            int[] count = new int[26];
            for (char c : str.toCharArray()) {
                count[c - 'a']++;
            }
            
            // 根据计数结果生成唯一键,格式为 #次数#次数... 避免不同计数拼接后冲突
            StringBuilder keyBuilder = new StringBuilder();
            for (int num : count) {
                keyBuilder.append('#').append(num);
            }
            String key = keyBuilder.toString();
            
            // 如果键不存在就先创建对应的列表
            if (!map.containsKey(key)) {
                map.put(key, new ArrayList<>());
            }
            // 将当前字符串加入对应分组
            map.get(key).add(str);
        }
        
        // 返回所有分组结果
        return new ArrayList<>(map.values());
    }
    
    // 测试示例
    public static void main(String[] args) {
        AnagramGroup solution = new AnagramGroup();
        String[] testStrs = {"eat", "tea", "tan", "ate", "nat", "bat"};
        List<List<String>> result = solution.groupAnagrams(testStrs);
        
        System.out.println("分组结果:");
        for (List<String> group : result) {
            System.out.println(group);
        }
    }
}

复杂度分析

这种方法的效率优势非常明显:

  • 时间复杂度:假设输入字符串数组长度为 n,每个字符串平均长度为 k,那么统计字符计数的时间是 O(n*k),生成键的时间也是 O(n*k),整体时间复杂度是 O(n*k),比带排序的 O(n*k log k) 更优。
  • 空间复杂度:需要存储哈希表和所有字符串,最坏情况下每个字符串都是独立的变位词组,空间复杂度是 O(n*k),和排序方法的空间复杂度相当。

场景扩展

如果输入的字符串包含大写字母、数字或者其他特殊字符,只需要调整计数数组的长度即可。比如要支持 ASCII 字符,可以把数组长度设为 128,用字符的 ASCII 码作为索引;如果要支持 Unicode 字符,也可以改用 HashMap<Character, Integer> 来统计计数,生成键的时候遍历这个 HashMap 即可,逻辑和上述代码基本一致。

Java变位词分组哈希映射字符计数时间复杂度优化算法实现修改时间:2026-05-24 12:16:13

免责声明:已尽一切努力确保本网站所含信息的准确性。网站部分内容来源于网络或由用户自行发表,内容观点不代表本站立场。本站是个人网站免费分享,内容仅供个人学习、研究或参考使用,如内容中引用了第三方作品,其版权归原作者所有。若内容触犯了您的权益,请联系我们进行处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。前端、网络、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握网站开发与运维所需的核心技术栈。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端逻辑,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。