图解题库 / 数组 · 快慢指针

26. 删除有序数组中的重复项

简单 含交互动画

学完这道你应该能: 说清它为什么用「快慢指针」,而不是死记步骤; 合上页面,自己默写出核心代码; 用 30 秒把思路讲清楚。

题目描述

一个有序数组,原地删掉重复的数,返回去重后的长度。

nums = [1, 1, 2, 2, 3]
输出 = 3 (前三个变成 1,2,3)

思路解析

i 往前走,挨个检查;j 指向下一个该放新数字的位置。发现新数字,就放到 j,然后 j 往前走一格。

准备:i = 0, j = 0:蓝色 i 是快指针,紫色 l 是慢指针 j,两个都从开头出发。

i = 0 · 第一个数:第一个数 1 肯定保留——它前面没数可以重复。

i = 0 · 放入:把 1 放到 j 位置(本来就在 0 号位),慢指针 j 前进到 1。

i = 1 · 看 1:当前 1 和它前一个 1 相同,重复了。跳过,j 不动,只让 i 继续走。

i = 2 · 看 2:当前 2 和前一个 1 不同,是新数字!该把它码到 j 位置了。

i = 2 · 放入:把 2 写到 1 号位(覆盖掉那个多余的 1),慢指针 j 前进到 2。看,前面已经是 [1, 2] 了。

i = 3 · 看 2:当前 2 和前一个 2 相同,重复,跳过。j 不动。

i = 4 · 看 3:当前 3 和前一个 2 不同,新数字!

i = 4 · 放入:把 3 写到 2 号位,慢指针 j 前进到 3。

结束:i 走完了。前 j = 3 个数 [1, 2, 3] 就是去重后的数组,返回长度 3。后面的数不用管。

快慢指针是数组题的万能套路:移除元素、移动零、删重复,都是 i 探路、j 安放。

参考代码(Python)

Python
1class Solution:
2    def removeDuplicates(self, nums):
3        j = 0                          # 慢指针:放新数的位置
4        for i in range(len(nums)):     # 快指针:逐个检查
5            if i == 0 or nums[i] != nums[i-1]:  # 是新数?
6                nums[j] = nums[i]      # 放到 j
7                j += 1                 # j 前进
8        return j

复杂度分析

  • 时间复杂度:O(n) —— i 只走一遍
  • 空间复杂度:O(1) —— 在原数组上改,不额外开空间

套路模板

移除元素、移动零、去重,都是把「该保留的」依次写到 j

Python
1# 原地处理:i 探路,j 安放
2j = 0
3for i in range(len(nums)):
4    if 该保留(nums[i]):
5        nums[j] = nums[i]
6        j += 1
7return j   # 前 j 个就是答案

易错点

  • if nums[i] != nums[i-1](i=0 越界) → ✅ if i==0 or nums[i] != nums[i-1](第一个数没有「前一个」)
  • 返回 j-1 或 j+1 → ✅ 返回 j(j 每写一次就 +1,正好等于个数)

以上文字与上方动画完全同一思路:先看动画建立直觉 → 读文字巩固 → 关掉页面自己默写一遍代码,能写出来才算真的掌握

下一题 →20. 有效的括号 ← 返回题库