当前位置: 首页 > java >正文

LeetCode经典题解:49、字母异位词分组

LeetCode经典题解:字母异位词分组

“字母异位词分组”是哈希表应用的经典题目,解法思路清晰但细节易混。本文用“场景化记忆法”帮你吃透解法,从代码逻辑到记忆技巧一网打尽。

一、题目描述

题目:给你一个字符串数组,请你将字母异位词组合在一起。可以按任意顺序返回结果列表。
字母异位词是由重新排列源单词的所有字母得到的新单词(例如,“eat”和“tea”是字母异位词)。

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

二、最优解法:哈希表 + 特征归一

方法一:排序法(直观高效)

代码实现
import java.util.*;class Solution {public List<List<String>> groupAnagrams(String[] strs) {// 哈希表:key是"特征值"(排序后的字符串),value是同组异位词列表Map<String, List<String>> map = new HashMap<>();for (String s : strs) {// 将字符串转换为字符数组,排序后作为"特征值"char[] chars = s.toCharArray();Arrays.sort(chars);String key = new String(chars);// 若key不存在则创建新列表,否则直接添加到对应列表map.computeIfAbsent(key, k -> new ArrayList<>()).add(s);}// 哈希表的值就是分组结果return new ArrayList<>(map.values());}
}
解法解析
  1. 核心逻辑:字母异位词排序后得到的字符串完全相同(例如“eat”和“tea”排序后都是“aet”),用排序后的字符串作为“特征值”,通过哈希表分组。
  2. 时间复杂度O(n * k log k)n 是字符串数量,k 是最长字符串长度,排序耗时 k log k)。
  3. 空间复杂度O(n * k)(哈希表存储所有字符串)。

方法二:字符频率法(适合长字符串)

代码实现
import java.util.*;class Solution {public List<List<String>> groupAnagrams(String[] strs) {Map<String, List<String>> map = new HashMap<>();for (String s : strs) {// 统计26个小写字母的出现次数int[] count = new int[26];for (char c : s.toCharArray()) {count[c - 'a']++;}// 将频率数组转为字符串作为key(例如"1,0,2,...")StringBuilder key = new StringBuilder();for (int num : count) {key.append(num).append(','); // 加逗号避免歧义(如11和1,1)}map.computeIfAbsent(key.toString(), k -> new ArrayList<>()).add(s);}return new ArrayList<>(map.values());}
}
解法解析
  1. 核心逻辑:字母异位词的字符频率完全相同(例如“eat”和“tea”的 e:1, a:1, t:1),用频率数组的字符串形式作为“特征值”分组。
  2. 优势:避免排序耗时,适合字符串长(k 大)但字符集小(如仅小写字母)的场景。

三、为什么这样解?—— 异位词的“共性”与分组逻辑

1. 异位词的本质

字母异位词的核心共性是“字符种类和数量完全相同,顺序不同”。因此,只要找到一种“归一化”方法(如排序、统计频率),就能将异位词映射到同一“特征值”。

2. 哈希表的作用

哈希表的“键值对”结构天然适合“分组”:

  • 键(key):异位词的“特征值”(排序后的字符串或频率字符串),确保同一组异位词映射到同一键。
  • 值(value):存储同一组的所有异位词,最终直接返回所有值的集合。

四、高效记忆技巧:把逻辑变成“整理文件”的场景

用生活化场景理解代码,记住“角色+动作”即可还原解法:

1. 角色赋值

  • 哈希表(map):扮演“文件柜”,每个抽屉(key)对应一组异位词。
  • 排序/频率统计:扮演“标签机”,给每个字符串打“特征标签”(确保异位词标签相同)。
  • 字符串数组(strs):扮演“一堆待整理的文件”,需要按标签分类放进文件柜。

2. 场景故事:整理文件的流程

(以排序法为例)
你是档案管理员,要把一堆文件(strs)按“内容相同、顺序不同”分类:
① 拿起一份文件(字符串),用“标签机”(排序)给它打标签(排序后的字符串,如“tea”→“aet”);
② 查看文件柜(map)里有没有这个标签的抽屉:

  • 有则直接把文件放进去;
  • 没有则新建抽屉(key),再放文件;
    ③ 所有文件处理完后,文件柜里的抽屉就是分组结果。

3. 两种方法的记忆点

方法标签机(特征值)适用场景一句话总结
排序法排序后的字符串字符串短、字符集大“排序归一,哈希分组”
频率统计法字符频率拼接的字符串字符串长、字符集小(如26字母)“统计频率做标签,哈希来归类”

4. 对比记忆:和“两数之和”的关联

两道题都用哈希表实现“分组/配对”,核心逻辑相通:

  • 两数之和:用哈希表找“补数”(配对);
  • 异位词分组:用哈希表按“特征值”归类(分组)。
    共同点:哈希表是“中介”,通过键值映射解决“关联/分组”问题

五、实战拓展:变种题巩固思路

  1. 判断两个字符串是否为异位词:直接比较排序后的结果或频率数组。
  2. 异位词中的最长单词:分组后找每组中最长的字符串。
  3. 区分大小写/包含数字的异位词:扩展频率数组(如考虑26大写+26小写+10数字,共62长度)。

通过“文件分类”的场景记忆,字母异位词分组的解法会变得很直观。记住:算法的核心是“找共性→用工具(哈希表)实现映射”,而非死记代码。多思考“如何定义特征值”,就能应对各种变种场景。

http://www.xdnf.cn/news/15029.html

相关文章:

  • 西部数据WD授权代理商-深圳同袍存储科技有限公司
  • 5种使用USB数据线将文件从安卓设备传输到电脑的方法
  • Sophix、Tinker 和 Robust 三大主流 Android 热修复框架的详细对比
  • C语言顺序表:从零开始,解锁数据结构之门!
  • 无人机三叶螺旋桨概述
  • git fetch的使用
  • OpenSearch 视频 RAG 实践
  • 【libm】 18 泛型绝对值函数 fabs(fabs.rs)
  • Canny边缘检测(cv2.Canny())
  • ACL协议:核心概念与配置要点解析
  • 从真人到数字分身:3D人脸扫描设备在高校数字人建模教学中的应用
  • 在 Mac 上使用 Git 拉取项目:完整指南
  • 【科研绘图系列】R语言探索生物多样性与地理分布的可视化之旅
  • BGP 路由优选属性(6)【Ogn】
  • 文件系统----底层架构
  • Java---IDEA
  • Redis性能基准测试
  • mac m1芯片 安装pd及win10系统
  • 【超详细】CentOS系统Docker安装与配置一键脚本(附镜像加速配置)
  • 深入了解 Vim 编辑器:从入门到精通
  • 三、C++ 的 python 绑定 pybind11
  • 【C++基础语法】
  • 如何把Arduino IDE中ESP32程序bin文件通过乐鑫flsah_download_tool工具软件下载到ESP32中
  • 【EGSR2025】材质+扩散模型+神经网络相关论文整理随笔(三)
  • SQL 索引与日志知识点详解及练习题​
  • Agent自动化与代码智能
  • HTML应用指南:利用GET请求获取全国永辉超市门店位置信息
  • 申请注册苹果iOS企业级开发者证书需要公司拥有什么规模条件
  • Spring boot整合dubbo+zookeeper
  • 《O-PAS™标准的安全方法》白皮书:为工业自动化系统筑起安全防线