题目描述
思路解析动画文字版
口诀:一张表 last 记每个数字「最后一次出现的下标」。每到一个数,先查上次位置算距离,再用这次下标覆盖。先查后更新。下面逐格演示。
指针 i 走到下标 0,值是 1。去表里查 1 之前在哪:表里还没有它。
1 是第一次出现,把它的下标 0 记进表里,继续往后扫。
指针 i 走到下标 1,值是 2。去表里查 2 之前在哪:表里还没有它。
2 是第一次出现,把它的下标 1 记进表里,继续往后扫。
指针 i 走到下标 2,值是 3。去表里查 3 之前在哪:表里还没有它。
3 是第一次出现,把它的下标 2 记进表里,继续往后扫。
指针 i 走到下标 3,值是 1。表里查到 1 上次在下标 0,这次距离是 3 − 0 = 3。
距离 3 超过了 k=2,这一对太远不算。把 1 的「最后下标」更新成 3,继续往后扫。
指针 i 走到下标 4,值是 4。去表里查 4 之前在哪:表里还没有它。
4 是第一次出现,把它的下标 4 记进表里,继续往后扫。
指针 i 走到下标 5,值是 5。去表里查 5 之前在哪:表里还没有它。
5 是第一次出现,把它的下标 5 记进表里,继续往后扫。
指针 i 走到下标 6,值是 6。去表里查 6 之前在哪:表里还没有它。
6 是第一次出现,把它的下标 6 记进表里,继续往后扫。
指针 i 走到下标 7,值是 6。表里查到 6 上次在下标 6,这次距离是 7 − 6 = 1。
距离 1 不超过 k=2,下标 6 和 7 这两个 6 挨得够近,条件满足,直接返回 true。
找到了高亮的这一对相等数字,且距离不超过 k,所以答案是 true。
三个高频追问:为什么存最后下标、滑动窗口写法、k=0 的边界。
参考代码
def containsNearbyDuplicate(nums, k): last = {} # 值 -> 最后出现的下标 for i, x in enumerate(nums): if x in last and i - last[x] <= k: return True # 相等且距离够近 last[x] = i # 更新这个值的最新下标 return False复杂度
- 时间:O(n),指针 i 把数组扫一遍,每个数的查表和更新都是 O(1)
- 空间:O(min(n, 用到的不同值个数)),哈希表最多记下数组里出现过的不同数字
易错点
面试追问把动画讲成自己的话
追问为什么哈希表里要存「最后一次」的下标,而不是第一次?
追问能不能用滑动窗口集合来做?
追问如果 k 是 0 会怎样?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
单词规律
LeetCode 290 · 简单 · 沿着 哈希套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题