双指针法适用于已排序数组的原地去重,核心是慢指针标记唯一元素末尾、快指针遍历找新值;未排序时需先排序,否则失效。

JavaScript 中数组去重用双指针法,主要适用于已排序数组的原地去重(即不新建数组、空间复杂度 O(1)),核心思想是用一个慢指针标记「当前已确认唯一元素的末尾位置」,快指针遍历找新元素。它不能直接用于未排序数组——否则会丢失顺序或漏去重,需先排序(时间复杂度升至 O(n log n))。
适用前提:数组必须有序
双指针去重依赖「相同元素相邻」这一特性。例如:[1,1,2,2,3] 可以正确压缩为 [1,2,3];但若输入是 [1,2,1,3,2],不排序直接双指针会得到 [1,2,1,3,2](完全无效)。
- 升序或降序均可,只要相同值连续出现
- 原始数组会被修改(原地操作),返回的是新长度,有效元素在前部
- 常见于 LeetCode 26 题(删除有序数组重复项)
标准双指针实现(升序数组)
慢指针 slow 指向已处理区域末尾(初始为 0),快指针 fast 从 1 开始扫描。当 nums[fast] !== nums[slow],说明遇到新值,把 nums[fast] 赋给 nums[++slow]。
function removeDuplicates(nums) {
if (nums.length === 0) return 0;
let slow = 0;
for (let fast = 1; fast < nums.length; fast++) {
if (nums[fast] !== nums[slow]) {
slow++;
nums[slow] = nums[fast];
}
}
return slow + 1; // 唯一元素个数
}调用后 nums 前 slow + 1 项为去重结果,如 [0,0,1,1,1,2,2,3,3,4] → 返回 5,nums 变为 [0,1,2,3,4,2,2,3,3,4](前 5 位有效)。
立即学习“Java免费学习笔记(深入)”;
扩展:保留最多 k 个重复项(如 LeetCode 80)
只需记录当前值已写入几次。用 count 计数,slow 仍指向下个可写位置:
- 若
nums[fast] === nums[slow - 1],且count ,则写入并 <code>count++ - 若不等,重置
count = 1,再写入
例如 k=2 时,[1,1,1,2,2,3] → [1,1,2,2,3](每个数最多留两个)。
未排序数组?别硬套双指针
强行对未排序数组用双指针去重,逻辑上不可行。正确做法分两步:
- 先用
nums.sort((a,b) => a - b)排序(注意数字排序要传比较函数) - 再用上述双指针逻辑
但此时总时间复杂度为 O(n log n),空间仍是 O(1)。如果更看重速度且允许额外空间,用 Set 一行解决:[...new Set(nums)](O(n) 时间,O(n) 空间,保持原顺序)。
不复杂但容易忽略:双指针高效的前提是有序。用错场景,再优雅的指针也白搭。


















