题目描述
思路解析动画文字版
核心做法:维护一张计数表 cnt。遍历 s 时每个字符 +1,遍历 t 时每个字符 -1。如果两个串字母完全一致,加进去的和减出来的会刚好抵消,所有计数都回到 0。
1. 看输入:输入 s = "anagram",t = "nagaram"。先做最快的判断:长度不等就直接 false。这里两者长度都是 7,可以继续。下方数组展示的是 s 的字符,右侧计数表 cnt 现在是空的。
2. 读 s[0]='a':遍历 s 的第 0 个字符 'a'(橙色)。先看清是哪个字符,下一步把它加进计数表。
3. 加:cnt['a'] +1 → 1:在计数表里给 'a' 加一,它现在的计数是 1。s 走完后,cnt 记录的就是 s 里每个字母各出现了几次。
4. 读 s[1]='n':遍历 s 的第 1 个字符 'n'(橙色)。先看清是哪个字符,下一步把它加进计数表。
5. 加:cnt['n'] +1 → 1:在计数表里给 'n' 加一,它现在的计数是 1。s 走完后,cnt 记录的就是 s 里每个字母各出现了几次。
6. 读 s[2]='a':遍历 s 的第 2 个字符 'a'(橙色)。先看清是哪个字符,下一步把它加进计数表。
7. 加:cnt['a'] +1 → 2:在计数表里给 'a' 加一,它现在的计数是 2。s 走完后,cnt 记录的就是 s 里每个字母各出现了几次。
8. 读 s[3]='g':遍历 s 的第 3 个字符 'g'(橙色)。先看清是哪个字符,下一步把它加进计数表。
9. 加:cnt['g'] +1 → 1:在计数表里给 'g' 加一,它现在的计数是 1。s 走完后,cnt 记录的就是 s 里每个字母各出现了几次。
10. 读 s[4]='r':遍历 s 的第 4 个字符 'r'(橙色)。先看清是哪个字符,下一步把它加进计数表。
11. 加:cnt['r'] +1 → 1:在计数表里给 'r' 加一,它现在的计数是 1。s 走完后,cnt 记录的就是 s 里每个字母各出现了几次。
12. 读 s[5]='a':遍历 s 的第 5 个字符 'a'(橙色)。先看清是哪个字符,下一步把它加进计数表。
13. 加:cnt['a'] +1 → 3:在计数表里给 'a' 加一,它现在的计数是 3。s 走完后,cnt 记录的就是 s 里每个字母各出现了几次。
14. 读 s[6]='m':遍历 s 的第 6 个字符 'm'(橙色)。先看清是哪个字符,下一步把它加进计数表。
15. 加:cnt['m'] +1 → 1:在计数表里给 'm' 加一,它现在的计数是 1。s 走完后,cnt 记录的就是 s 里每个字母各出现了几次。
16. s 统计完成:s 遍历结束,计数表记下了 s 里每个字母的个数:a×3、n×1、g×1、r×1、m×1。下一阶段拿 t 的每个字符来抵消,把计数一个个减回去。
17. 减:t[0]='n' 计数 -1:遍历 t 的第 0 个字符 'n'(黄色高亮)。在计数表里给 'n' 减一,它现在的计数是 0。s 加的、t 减的正好对应,计数在一步步归零。
18. 减:t[1]='a' 计数 -1:遍历 t 的第 1 个字符 'a'(黄色高亮)。在计数表里给 'a' 减一,它现在的计数是 2。s 加的、t 减的正好对应,计数在一步步归零。
19. 减:t[2]='g' 计数 -1:遍历 t 的第 2 个字符 'g'(黄色高亮)。在计数表里给 'g' 减一,它现在的计数是 0。s 加的、t 减的正好对应,计数在一步步归零。
20. 减:t[3]='a' 计数 -1:遍历 t 的第 3 个字符 'a'(黄色高亮)。在计数表里给 'a' 减一,它现在的计数是 1。s 加的、t 减的正好对应,计数在一步步归零。
21. 减:t[4]='r' 计数 -1:遍历 t 的第 4 个字符 'r'(黄色高亮)。在计数表里给 'r' 减一,它现在的计数是 0。s 加的、t 减的正好对应,计数在一步步归零。
22. 减:t[5]='a' 计数 -1:遍历 t 的第 5 个字符 'a'(黄色高亮)。在计数表里给 'a' 减一,它现在的计数是 0。s 加的、t 减的正好对应,计数在一步步归零。
23. 减:t[6]='m' 计数 -1:遍历 t 的第 6 个字符 'm'(黄色高亮)。在计数表里给 'm' 减一,它现在的计数是 0。s 加的、t 减的正好对应,计数在一步步归零。
24. 检查计数表:t 遍历结束,回头看计数表:a=0、n=0、g=0、r=0、m=0,全部归零。这说明 s 加进去的和 t 减出来的字母完全一致,t 确实是 s 的异位词。
25. 返回答案:计数表全为 0,返回 true(绿色标出完全匹配的 s)。整个过程把 s、t 各扫一遍,只用一张大小固定(最多 26 个字母)的计数表。
记住这题的骨架:用一张计数表,s 加 t 减,靠「最后全为 0」来判断两个串字母种类和个数是否完全一致。
参考代码
class Solution: def isAnagram(self, s: str, t: str) -> bool: if len(s) != len(t): return False cnt = [0] * 26 for ch in s: cnt[ord(ch) - ord("a")] += 1 for ch in t: cnt[ord(ch) - ord("a")] -= 1 if cnt[ord(ch) - ord("a")] < 0: return False return True复杂度
- 时间复杂度:O(n),s、t 各扫一遍
- 空间复杂度:O(1),计数表固定 26 个字母
易错点
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
两数之和
LeetCode 1 · 简单 · 沿着 数组 & 哈希 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题