题目描述
思路解析动画文字版
最直白的做法:发现重复就删掉它,后面的元素整体往前挪一格。每删一次都要搬一长串,最坏要搬 n 的平方次,太慢。
换个思路:慢指针 slow 指向「最后一个已确定的不重复数」;快指针 fast 一路向前。fast 撞到和 slow 不一样的新数,就 slow 前进一格、把新数写过去。slow 左边永远是去好重的结果。
准备 · slow=0, fast=1:紫色 slow 停在 0 号位——第一个数没有可比的前一个,天然保留。蓝色 fast 从 1 号位出发去找新数。
fast=1 · 比一比:fast 指的 1,和 slow 指的 1 一样,是重复数。slow 不动,只让 fast 往前走。
fast=2 · 比一比:fast 指的 2,和 slow 指的 1 不一样,是个新数字!该把它码到 slow 后面了。
fast=2 · slow 先进位:写之前先让 slow 前进一格,到 1 号位。这个格子原来放着多余的 1,正好拿来安放新数。
fast=2 · 覆盖写入:把 2 写进 1 号位,覆盖掉原来多余的 1。数组前段变成 [1, 2],去重结果又长了一位。
fast=3 · 比一比:fast 指的 2,和 slow 指的 2 相同,又是重复。slow 不动,fast 继续往前。
fast=4 · 比一比:fast 走到最后,指的 3,和 slow 指的 2 不一样,又是新数字。
fast=4 · slow 先进位:老规矩,先让 slow 前进到 2 号位,腾出新数该放的格子。
fast=4 · 覆盖写入:把 3 写进 2 号位。前段变成 [1, 2, 3],三个不重复的数都归位了。
结束 · 返回 slow+1:fast 走完了。slow 停在 2 号位,前 slow+1 也就是 3 个数 [1, 2, 3] 就是去重结果,返回 3。后面的旧数据不用管。
灵魂帧慢放 · 一次完整写入:把核心动作再慢放一遍:fast 找到新数 3,slow 先进一格到 2,再把 3 覆盖写进去。重复数就只让 fast 走、slow 原地不动。记住这两拍。
slow 是写指针、fast 是读指针。读到和 slow 不同的新数,才让 slow 进位并写入。删除有序数组重复项、移除元素、移动零,全是这套快慢指针。
雷区实演 · 全相同 [2,2,2]:试个全是 2 的数组:fast 每次比都相同,slow 一直停在 0。返回 slow+1 = 1,正好——去重后只剩一个 2。先进位的写法在这里也不会误覆盖。
面试追问:面试最常追:为何不用哈希、保留两个怎么改、无序还行不行——答案都扣在「升序使重复相邻」这个前提上。
迁移阶梯:练熟这题,再去同类题迁移:LC27 改「保留条件」、LC80 改「比较对象」、LC283 改成交换。结构都一样,遇到卡点可以问问 AI 助教小欧,或到通关训练里实战一遍。
边界三连:三个边界都要过:空数组返回 0,单元素返回 1,全相同也返回 1。fast 从 1 起步天然处理了单元素和空。
参考代码
class Solution: def removeDuplicates(self, nums): if not nums: return 0 slow = 0 # 去重边界 for fast in range(1, len(nums)): # 快指针探路 if nums[fast] != nums[slow]: # 遇到新数 slow += 1 # 先进位 nums[slow] = nums[fast] # 再覆盖写入 return slow + 1 # 长度 = slow+1复杂度
- 时间复杂度:O(n),fast 从头到尾只走一遍,slow 只增不减,总共 n 步
- 空间复杂度:O(1),全程在原数组上覆盖,不额外开空间
可套用的代码模板
骨架固定:slow 写、fast 读、命中判据才进位写入。本题判据是 nums[fast] != nums[slow];换成 != val 就是移除元素,换成 != nums[slow-1] 就是最多留两个。
# 原地保留「该留的元素」,去重/移除都套这个骨架slow = 0 # 写指针:已确定边界for fast in range(1, len(nums)): # 读指针:探路 if 是要保留的新元素(nums[fast]): # 改这一行的判据 slow += 1 nums[slow] = nums[fast]return slow + 1 # 结果长度易错点
面试追问把动画讲成自己的话
追问这题为什么不能用哈希表去重?
追问如果允许每个数最多保留两个(LC80)怎么改?
追问数组无序还能这么做吗?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。再去主线里挑下一道练手。
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题