题目描述
思路解析动画文字版
最直接是每个数和后面所有数比较。数组一长,比较次数会爆炸。
用 set 记录已经见过的数。每来一个数先查,再加入。命中立刻返回 true。
空 set 开始:seen 为空,准备从左到右扫描。
读到 1:1 不在 seen 中,加入。
读到 2:2 也没见过,加入。
读到 3:3 没见过,继续加入。
再次读到 1 · 查到了:扫到第二个 1,先查 seen,发现 1 那一行已经在里面。
命中重复 · 返回 true:下标 0 和下标 3 是同一个值,命中重复,立刻返回 true。
没有命中才 false:如果扫完整个数组都没命中,最后才返回 false。
查到重复就立刻停,不需要继续扫描。
边界三连:单元素、相邻重复、不相邻重复,刚好覆盖 set 的三个基本分支。
雷区实演 · 先 add 会错:如果先把当前 1 放进去,再查 seen,当前 1 会命中自己。必须先查。
面试追问 1:可以排序后看相邻,但时间变 O(nlogn),且会改变数组顺序。
面试追问 2:命中时直接返回当前 x,它就是第一个重复的值。
面试追问 3:没有重复时,seen 会存下所有元素。
这题学完不要乱跳,下一步去 对应专题 连刷同类题;卡住时用 AI 答疑追问“为什么这一步成立”,比只背答案更稳。
参考代码
class Solution: def containsDuplicate(self, nums): seen = set() for x in nums: if x in seen: return True seen.add(x) return False复杂度
- 时间复杂度:O(n),每个元素最多查一次、加一次
- 空间复杂度:O(n),最坏全部不重复,需要存 n 个数
可套用的代码模板
记住三句话就能背下来:先查历史、命中即停、没见过再记下。换成 LC219、LC349 这类“见过吗”问题,只要改 set 里存什么、命中时做什么,主干一字不动。
# 模型:一边遍历,一边用 set 记“我见过谁”seen = set()for x in nums: if x in seen: # 先查历史 return True # 命中即停 seen.add(x) # 没见过再记下return False # 扫完都没命中易错点
面试追问把动画讲成自己的话
追问能不用额外空间吗?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
有效的字母异位词
LeetCode 242 · 简单 · 沿着 数组 & 哈希 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题