news 2026/2/17 20:47:28

力扣 “字母异位词分组” 终极解法:排序法 + 计数法双方案(附效率对比)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
力扣 “字母异位词分组” 终极解法:排序法 + 计数法双方案(附效率对比)

大家好,今天深度拆解力扣中等题「字母异位词分组」的两种核心解法 ——排序法(简洁易实现)计数法(高效优化版),并对比两者的适用场景,帮你彻底掌握这道经典题!

一、题目回顾

给定一个字符串数组strs,将字母异位词(字母种类 / 数量相同、排列不同的字符串)分组,返回所有分组后的列表。

  • 示例:输入["eat","tea","tan","ate","nat","bat"]→ 输出[["eat","tea","ate"],["tan","nat"],["bat"]]
二、核心思路:给异位词 “打标签”

字母异位词的核心特征是「字符组成完全相同」,因此只要能给每组异位词生成唯一的标签(key),就能用哈希表实现分组。两种解法的本质都是 “生成唯一 key + 哈希表分组”,区别仅在于「生成 key 的方式」。

三、方案 1:排序法(简洁易上手)
1. 核心逻辑

将每个字符串的字符排序,异位词排序后会得到相同的字符串(如eat/tea排序后都是aet),以此作为哈希表的 key。

2. 代码实现
import java.util.*; class Solution { // 排序法:简洁易实现,适合字符串较短的场景 public List<List<String>> groupAnagrams(String[] strs) { // key:排序后的字符串;value:对应异位词列表 Map<String, List<String>> map = new HashMap<>(); for (String str : strs) { // 1. 字符数组排序,生成唯一key char[] chars = str.toCharArray(); Arrays.sort(chars); String key = new String(chars); // 2. 哈希表分组:无则新建列表,有则直接添加 List<String> list = map.getOrDefault(key, new ArrayList<>()); list.add(str); map.put(key, list); } // 3. 提取所有分组结果 return new ArrayList<>(map.values()); } }
3. 复杂度分析
  • 时间复杂度:O(n×k log k)n= 字符串数量,k= 字符串最大长度;排序单字符串的时间是O(k log k),遍历 + 排序整体为O(n×k log k)
  • 空间复杂度:O(n×k)(存储哈希表的键和所有字符串)。
4. 适用场景

字符串长度k较小(如 k≤20),追求代码简洁性,无需极致性能。

四、方案 2:计数法(高效优化版)
1. 核心逻辑

排序法的瓶颈在 “字符排序”,计数法直接统计每个字符串中 26 个字母的出现次数(如eat的计数为a:1, e:1, t:1),将计数结果拼接成唯一 key,把单字符串处理时间从O(k log k)降至O(k)

2. 代码实现
import java.util.*; class Solution { // 计数法:时间优化版,适合字符串较长的场景 public List<List<String>> groupAnagrams(String[] strs) { Map<String, List<String>> map = new HashMap<>(); for (String str : strs) { // 1. 初始化26字母计数数组(a-z对应下标0-25) int[] count = new int[26]; // 2. 统计每个字符出现次数 for (char c : str.toCharArray()) { count[c - 'a']++; // 'a'→0,'b'→1,以此类推 } // 3. 生成唯一key(用逗号分隔避免数字歧义,如11和1+1) StringBuilder sb = new StringBuilder(); for (int num : count) { sb.append(num).append(","); } String key = sb.toString(); // 4. 哈希表分组(逻辑同排序法) List<String> list = map.getOrDefault(key, new ArrayList<>()); list.add(str); map.put(key, list); } return new ArrayList<>(map.values()); } }
3. 关键优化点
  • 计数数组替代排序:仅遍历字符串一次(O(k)),避免排序的O(k log k)开销;
  • 逗号分隔生成 key:防止 “计数 1 + 计数 1” 拼接成 “11”,与 “计数 11” 混淆(如"aa""k"的计数直接拼接会都是2,加逗号后为2,0,...0,...1,...,可区分)。
4. 复杂度分析
  • 时间复杂度:O(n×k)(仅遍历字符串和计数数组,无排序开销);
  • 空间复杂度:O(n×k)(额外占用计数数组,但可忽略,整体仍为O(n×k))。
5. 适用场景

字符串长度k较大(如 k≥100),追求极致时间效率。

五、两种方案对比总结
解法时间复杂度空间复杂度代码简洁度适用场景
排序法O(n×k log k)O(n×k)字符串短、追求代码简洁
计数法O(n×k)O(n×k)字符串长、追求时间效率
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/7 19:32:35

互联网大厂Java求职面试全场景模拟:核心技术与业务实战解析

第一轮:基础与核心技术 面试官:你好,谢飞机,我们先从Java SE和构建工具开始。请你简述一下Java 8和Java 11的主要区别,以及你平时用Maven还是Gradle? 谢飞机:Java 8引入了Lambda表达式和StreamAPI,Java 11增加了HttpClient等新特性。我平时用Maven,项目管理方便。 面试官:很好…

作者头像 李华
网站建设 2026/2/7 23:57:48

RuoYi-Cloud-Plus SSE推送:5分钟实现微服务实时通信的终极指南

RuoYi-Cloud-Plus SSE推送&#xff1a;5分钟实现微服务实时通信的终极指南 【免费下载链接】RuoYi-Cloud-Plus 微服务管理系统 重写RuoYi-Cloud所有功能 整合 SpringCloudAlibaba、Dubbo3.0、Sa-Token、Mybatis-Plus、MQ、Warm-Flow工作流、ES、Docker 全方位升级 定期同步 项…

作者头像 李华
网站建设 2026/2/7 20:41:14

Notally开源笔记应用:7大核心功能完整使用指南

Notally开源笔记应用&#xff1a;7大核心功能完整使用指南 【免费下载链接】Notally A beautiful notes app 项目地址: https://gitcode.com/gh_mirrors/no/Notally Notally是一款专为Android平台设计的开源笔记应用&#xff0c;以其简洁美观的界面和强大的本地优先功能…

作者头像 李华
网站建设 2026/2/7 1:58:17

EmotiVoice坚持技术向善原则

EmotiVoice&#xff1a;在声音的温度与技术的边界之间 你有没有想过&#xff0c;有一天AI不仅能“说话”&#xff0c;还能“共情”&#xff1f;当语音助手用带着一丝关切的语调问你“今天过得累吗”&#xff0c;当虚拟角色在游戏里因剧情转折而哽咽落泪&#xff0c;当视障用户听…

作者头像 李华
网站建设 2026/2/16 12:56:52

企业级物品租赁系统管理系统源码|SpringBoot+Vue+MyBatis架构+MySQL数据库【完整版】

摘要 随着共享经济的快速发展&#xff0c;企业级物品租赁系统成为提升资源利用率、降低运营成本的重要工具。传统租赁模式存在管理效率低、数据不透明、用户体验差等问题&#xff0c;亟需通过数字化手段优化业务流程。该系统旨在为企业提供高效、安全的租赁管理平台&#xff0c…

作者头像 李华
网站建设 2026/2/7 12:58:31

Java SpringBoot+Vue3+MyBatis html+css在线英语阅读分级平台系统源码|前后端分离+MySQL数据库

摘要 随着全球化进程的加速和信息技术的快速发展&#xff0c;英语阅读能力的重要性日益凸显。传统的英语学习方式往往缺乏个性化分级和实时反馈机制&#xff0c;导致学习效率低下。在线英语阅读分级平台通过智能化的分级算法和数据分析&#xff0c;能够为不同水平的用户提供适合…

作者头像 李华