删除排序数组中的重复项 II
数组 双指针题目描述
给定一个已排序的数组 nums,你需要 原地 删除重复出现的元素,使得每个元素 最多出现两次,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须在 原地修改输入数组 并在使用 O(1) 额外空间的条件下完成。
与上一题的区别:上一题每个元素最多保留 1 次,本题最多保留 2 次。
思路分析
数组已排序,重复元素一定相邻。使用 双指针(快慢指针)法:
- 慢指针 (slow):指向下一个可以写入的位置,初始值为
2。 - 快指针 (fast):从索引
2开始遍历,逐一判断当前元素是否可以保留。
前两个元素无论如何都保留(即使它们相同),因此两个指针都从索引 2 出发。
关键判断条件
因为数组有序,nums[slow - 2] 是已保留区域的倒数第二个元素。若 nums[fast] 与它不同,说明该元素在已保留区域中出现次数还不到 2 次,可以写入;否则跳过。
算法步骤
- 如果数组为空或长度
<= 2,直接返回nums.length(天然满足每个元素最多出现 2 次)。 - 初始化
slow = 2,fast从索引2开始遍历。 - 若
nums[fast] !== nums[slow - 2],将nums[fast]写入nums[slow],然后slow++。 - 遍历结束,返回
slow,即有效元素的个数。
示例代码
复杂度分析
- 时间复杂度:
O(n),其中n是数组的长度。只需遍历一次数组。 - 空间复杂度:
O(1),只使用了两个额外的索引变量。
示例演示
以 nums = [1, 1, 1, 2, 2, 3] 为例,逐步追踪双指针的移动:
最终 slow = 5,nums 前 5 项为 [1, 1, 2, 2, 3]。