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

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.lryc.cn/news/583816.html

相关文章:

  • Wisdom SSH:探索AI助手在复杂运维任务中的卓越表现
  • 6 如何向量化人工智能算法
  • 低版本hive(1.2.1)UDF实现清除历史分区数据
  • hive小文件问题
  • RabbitMQ 消息队列:从入门到Spring Boot实战
  • MySQL(127)如何解决主从同步失败问题?
  • XMAPP MySQL 启动后自动停止
  • adb 简介与常用命令
  • 线上事故处理记录
  • mx6ull-裸机学习实验15——RTC 实时时钟实验
  • 浪潮CD1000-移动云电脑-RK3528芯片-2+32G-开启ADB ROOT破解教程
  • MySQL断开连接后无法正常启动解决记录
  • 第一次搭建数据库
  • 壁仞 k8s 兼容
  • 力扣hot100速通(7.9)|49.字母异位词分组 128.最长连续序列 283.移动零 11.盛最多水的容器 42.接雨水
  • Swift 图论实战:DFS 算法解锁 LeetCode 323 连通分量个数
  • 力扣面试150题--全排列
  • leetcode 3440. 重新安排会议得到最多空余时间 II 中等
  • Leetcode力扣解题记录--第42题 接雨水(动规和分治法)
  • 图解LeetCode:79递归实现单词搜索
  • 【LeetCode100】--- 1.两数之和【复习回滚】
  • 力扣-73.矩阵置零
  • 力扣-54.螺旋矩阵
  • 每天一个前端小知识 Day 29 - WebGL / WebGPU 数据可视化引擎设计与实践
  • C++11 std::is_sorted 和 std::is_sorted_until 原理解析
  • 邀请函 | 知从科技邀您共赴2025 RISC-V 中国峰会
  • 使用 Qlib 获取股票数据
  • 从零开始的语言模型构建 CS336 第一课(一)
  • 数字孪生系统如何助力汽车零部件企业实现虚拟智控
  • Allegro PCB 手动添加元器件全流程解析