双指针法是有序数组去重最高效方法,利用排序特性,slow指向下标、fast遍历,遇新元素则slow++并赋值,最终长度为slow+1;需处理边界,支持扩展至最多保留两次。

双指针法是处理有序数组去重最常用、最高效的方法,核心在于利用数组已排序的特性,用一个指针遍历,另一个指针记录结果位置,避免额外空间开销。
快慢指针分工明确
定义两个指针:slow(慢指针)指向当前不重复元素应存放的位置,fast(快指针)负责遍历整个数组。初始时 slow = 0,fast 从 1 开始扫描。
- 当 nums[fast] ≠ nums[slow],说明遇到新元素,执行 slow++ 后赋值 nums[slow] = nums[fast]
- 当 nums[fast] == nums[slow],跳过,fast 继续前移
- 最终有效长度为 slow + 1(因为 slow 是下标,个数要加 1)
注意边界与初始化细节
数组为空或只有一个元素时需单独处理,否则可能越界。推荐统一写法:先判断 length ≤ 1,直接返回 length;否则再启动双指针逻辑。
- slow 始终代表「已确认无重复的最后一个元素下标」
- fast 不回退,只向前走,保证时间复杂度 O(n)
- 原地修改,不使用额外数组,空间复杂度 O(1)
区分「移除重复项」和「保留最多两次」
基础题要求每个元素只出现一次;进阶题(如 LeetCode 80)允许每个元素最多出现两次。这时 slow 需跟踪上一个“可写入位置”的前一个值是否已填满两次。
- 方法:若 nums[fast] == nums[slow - 1] 且 nums[fast] == nums[slow - 2],跳过
- 否则仍按 slow++ → 赋值流程处理
- 本质是把 slow 从“位置指针”扩展为“频次感知指针”
代码骨架简洁可复用
模板化写法便于快速应对同类题(如移除指定值、合并有序数组等):
- 初始化 slow = 0,fast 从 1 或 slow+1 开始
- for 循环驱动 fast,条件判断决定是否更新 slow
- 返回 slow + 1 作为新数组长度
- 实际调用时,只需改判断逻辑,结构不变
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











