242. 有效的字母异位词
难度:简单 | 主题:哈希表 / 字符串 / 排序
题目
给定两个字符串 s 和 t,判断 t 是否是 s 的字母异位词(每个字符出现次数相同,顺序可以不同)。
示例
s = "anagram", t = "nagaram" → true
s = "rat", t = "car" → false
思路
先讲个故事:药房的药材盘点
药房有两张药方,都写着”当归、甘草、人参”——但顺序不一样。药童需要判断:这两张方子是不是 同样的药材,同样份量?
把药材倒进 26 个抽屉(对应 a-z),每味药出现一次就放一颗豆子。两张方子都走完,每个抽屉的豆子数一样 → 同一张方子。
引导式推导:从排序到计数
思路一:排序法
异位词排序后字符串一样:
sorted("anagram") → "aaagmnr"
sorted("nagaram") → "aaagmnr"
# 相等 → 异位词
一行搞定,但排序 O(n log n)。
思路二:计数法(本质更优)
统计每个字符出现次数,一加一减,最后全零 → 异位词。
graph LR A["s 的每个字符 +1"] --> B["计数数组"] C["t 的每个字符 -1"] --> B B --> D{"所有位置<br/>都归零?"} D -->|"是"| E["true"] D -->|"否"| F["false"]
计数数组大小固定为 26(仅限小写字母),O(1) 额外空间。
两种解法对比
| 做法 | 时间 | 空间 | 场景 |
|---|---|---|---|
| Counter 比较 | O(n) | O(n) | 通用,Unicode 也支持 |
| 数组计数 | O(n) | O(1) | 字符集有限(如 a-z) |
| 排序比较 | O(n log n) | O(n) | 代码最短,备选 |
代码
from collections import Counter
def isAnagram(self, s, t):
return Counter(s) == Counter(t) # Counter 逐项比较频率分布
复杂度
| 指标 | 值 | 解释 |
|---|---|---|
| 时间 | O(n) | 遍历两个字符串各一次 |
| 空间 | O(n) | Counter 字典存字符频率 |
实战考量
延伸思考
Q:你能写一个不用 Counter 的版本吗?
A:用长度为 26 的数组(仅限小写字母):counter[ord(c) - ord('a')] += 1。空间 O(1) 因为大小固定。建议先写这个版本,再提 Counter 一行版。
Q:如果字符集是 Unicode,有上百万个字符呢?
A:数组法不可行——需要用哈希表 Counter。Unicode 范围太大,固定数组会浪费巨量空间。
Q:如果要求 O(1) 空间呢?
A:排序法。原地排序(如快排)理论上 O(log n) 栈空间,实践中可以接受作为”近乎 O(1)“的方案。
Q:能否只用一次遍历?
A:可以——先用 Counter 统计 s,遍历 t 时逐字符减,一旦发现负数直接返回 false。最后再检查是否所有计数归零。
易错点
-
Counter(s) == Counter(t)是逐元素比较频率,不是比较长度 -
数组计数先检查
len(s) != len(t)快速返回 false -
ord(c) - ord('a')偏移计算,下标范围 0-25 -
进阶字符集(Unicode)时不要用固定数组
生活类比
字符计数 → 药房抽屉
26 个抽屉对应 26 个字母。第一张方子的每味药往对应抽屉放一颗豆子,第二张方子每味药取出一颗。最后所有抽屉都空了 → 两张方子一模一样。
注意小写字母场景下这 26 个抽屉本身不占额外空间(固定大小)。
相关题目
| 题目 | 关系 |
|---|---|
| 49字母异位词分组 | 同族扩展,从判断一对到分组全部 |
→ 返回题单:LeetCode学习路线图 > 一、数组与哈希(含双指针、矩阵)
速记卡(面试闪卡)
Q1:一句话讲清「242. 有效的字母异位词」到底是什么?
A:判断两个字符串是否为字母异位词——字符种类与次数相同、顺序可不同。
Q2:思路 —— 怎么理解?
A:像药房按 26 个抽屉盘点两味方子的药材份量,数同则同方(Anagram,字母异位词)。
Q3:代码 —— 怎么理解?
A:一行 Counter 比对两串频率即可,无需排序(Counter,计数器)。
Q4:复杂度 —— 怎么理解?
A:时间 O(n) 遍历两串,空间 O(n) 存频率;数组法空间 O(1)(Time Complexity,时间复杂度)。
Q5:实战考量 —— 怎么理解?
A:字符集有限用数组更省,Unicode 用哈希;先比长度可秒拒(Edge Case,边界情况)。
Q6:核心速记主线有哪些?
-
定义:字符频率完全相同即为异位词
-
排序法 O(n log n),计数法 O(n) 更优
-
数组计数 O(1) 空间,仅限小写字母
-
先判长度不等可快速返回
口诀
A:字母异位词,频率要相等
排序对一遍,计数更聪明
数组省空间,哈希管万字符
先看长度差,秒拒不费神