Skip to content

双指针技巧:快慢指针

场景引入

给你一个有序数组,要求原地删除重复元素,返回去重后的长度。不能使用额外数组,只能在原数组上操作。

暴力做法是每遇到重复就把后面的元素整体前移,时间复杂度 O(n²)。有没有办法一次遍历就搞定?

快慢指针就是解决这类原地修改数组问题的利器。核心思想:slow 指针维护结果区域的边界,fast 指针负责扫描整个数组。两个指针同向而行,fast 跑得快,slow 跑得慢,因此叫"快慢指针"。

核心思路

快慢指针的通用框架:

javascript
function fastSlowPointer(nums) {
  let slow = 0;

  for (let fast = 0; fast < nums.length; fast++) {
    if (/* fast 指向的元素满足保留条件 */) {
      nums[slow] = nums[fast];
      slow++;
    }
  }

  return slow; // slow 就是结果数组的长度
}

关键点:

  1. slow 指针左边(不含 slow)的元素都是已确认保留的结果
  2. fast 指针负责逐个扫描,判断当前元素是否该保留
  3. 满足条件时,把 fast 处的值赋给 slow 处,然后 slow 前进
  4. 最终 slow 就是结果长度

可视化演示

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

加载可视化中...

代码实现

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

javascript
function removeDuplicates(nums) {
  if (nums.length === 0) return 0;
  let slow = 0;
  let fast = 1;

  while (fast < nums.length) {
    if (nums[fast] !== nums[slow]) {
      slow++;
      nums[slow] = nums[fast];
    }
    fast++;
  }

  return slow + 1;
}

思路:有序数组中,相同元素一定相邻。fast 每次和 slow 比较,不同就保留。

LC 27. 移除元素

javascript
function removeElement(nums, val) {
  let slow = 0;

  for (let fast = 0; fast < nums.length; fast++) {
    if (nums[fast] !== val) {
      nums[slow] = nums[fast];
      slow++;
    }
  }

  return slow;
}

思路:fast 扫描所有元素,不等于 val 的就保留到 slow 位置。

LC 283. 移动零

javascript
function moveZeroes(nums) {
  let slow = 0;

  for (let fast = 0; fast < nums.length; fast++) {
    if (nums[fast] !== 0) {
      // 交换而非覆盖,保证零被移到后面
      let temp = nums[slow];
      nums[slow] = nums[fast];
      nums[fast] = temp;
      slow++;
    }
  }
}

思路:和"移除元素"几乎一样,区别在于用交换代替覆盖,这样零会自然移到数组末尾。

三道题的统一视角

题目保留条件操作方式返回值
LC 26 删除重复项nums[fast] !== nums[slow]覆盖slow + 1
LC 27 移除元素nums[fast] !== val覆盖slow
LC 283 移动零nums[fast] !== 0交换无(原地修改)

可以看到,三道题本质上是同一个框架,只是保留条件和操作方式略有不同。

复杂度分析

  • 时间复杂度:O(n)。fast 指针遍历一次数组,slow 指针最多移动 n 次。
  • 空间复杂度:O(1)。只使用了两个指针变量,原地修改。

LeetCode 练习

按难度递进:

  1. LC 26. 删除有序数组中的重复项(简单)
  2. LC 27. 移除元素(简单)
  3. LC 283. 移动零(简单)
  4. LC 80. 删除有序数组中的重复项 II(中等)— 每个元素最多保留两次
  5. LC 844. 比较含退格的字符串(简单)— 从后往前的快慢指针变体

面试算法可视化图解