题目描述
思路解析动画文字版
一边扫一边删 val,每删一个,后面的元素都要整体往前挪一格,最坏要挪 n 的平方次;而且删完下标容易跳过下一个元素。换个思路:别删,把要留的写到前面。
fast 从左到右扫每个元素;只要 nums[fast] 不等于 val,就把它写到 nums[slow],然后 slow 前进一格。不变量:nums[0:slow] 永远是已确认要保留的元素,长度就是 slow。
初始化 · slow=0, fast 待出发:slow 等于 0,表示前面干净的前缀现在是空的。fast 还没开始扫,下一个要保留的元素该写到 0 号位。
fast=0 · nums[0]=3 等于 val:第一个数就是要移除的 3。它不能进前缀,所以 slow 不动,仍然守着 0 号位,等下一个该保留的元素。
fast=1 · 找到要保留的 2:fast 走到 1 号位,值是 2,不等于 val,要保留。它该被写到 slow 指着的 0 号位。
fast=1 · 写入 0 号位:把 2 写到 0 号位,数组变成 [2,2,2,3],前缀第一格定下来了。注意此刻 slow 还没动,下一帧才进位。
fast=1 · slow 前进到 1:因为放进了一个保留元素,slow 才前进到 1。颜色约定一句话:绿色=这一格刚被写入,变暗=已确认的前缀。现在 nums[0:1] 是有效前缀 [2],下一个该写到 1 号位。
fast=2 · 又找到要保留的 2:fast 走到 2 号位,值还是 2,要保留。它该写到 slow 现在指着的 1 号位。
fast=2 · 写入 1 号位,slow → 2:把第二个 2 写到 1 号位(值刚好相同),slow 再进位到 2。现在前缀 nums[0:2] 是 [2,2],已经攒到两个保留元素。
fast=3 · nums[3]=3 等于 val:最后一个数又是 3,要移除。它不写入前缀,slow 保持 2 不动。
扫描结束 · 返回 slow:fast 扫完整个数组,返回 slow 等于 2。判题只看前两个位置是不是不等于 3 的元素;后面的 [2,3] 是无效尾部,留什么都行。
只要题目说「原地保留一部分元素」,就先问两件事:前缀里该放什么、slow 什么时候才前进。本题的「合格」就是「不等于 val」。
雷区实演 · 全等于 val:极端例子:全是要删的 3。fast 扫完三个都跳过,从没写入,slow 一直停在 0,返回 0。如果你写成「slow 每轮都加」,这里就会错误返回 3。
面试追问:面试常追问覆盖写的安全性和「写次数」优化,这正是双指针的核心理解点。
迁移阶梯:把这题练到能复述后,去同类题里迁移:先复用 slow 写指针的定义,再只改「合格」条件。想不通时随时问小欧,或到通关训练里实战一遍。
边界三连:边界先看空数组、单元素,再看「全是 val」这种会让 slow 全程不动的极端样例。
参考代码
class Solution: def removeElement(self, nums, val): slow = 0 for fast in range(len(nums)): if nums[fast] != val: nums[slow] = nums[fast] slow += 1 return slow复杂度
- 时间复杂度:O(n),fast 从左到右扫一遍,slow 只增不减,指针总共只走一遍
- 空间复杂度:O(1),只用 slow、fast 两个指针,原地覆盖写,不开新数组
可套用的代码模板
记住这个挖空骨架:fast 读、slow 写、合格才写并进位。换一道「原地保留/去重」题,只需把 keep() 这一行条件改掉,其余原封不动。
# 「原地保留符合条件的元素」通用骨架slow = 0 # 写指针:下一个该写的位置for fast in range(len(nums)): # 读指针:扫每个元素 if keep(nums[fast]): # 合格条件(本题:!= val) nums[slow] = nums[fast] slow += 1return slow # slow 左边即结果,长度 = slow易错点
面试追问把动画讲成自己的话
追问覆盖写会不会把还没扫到的元素弄丢?
追问如果要删的元素很少,有没有更省「写次数」的写法?
追问这题和 LC26 删除有序数组重复项有什么关系?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
找出字符串中第一个匹配项的下标
LeetCode 28 · 中等 · 沿着 数组 & 哈希 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题