双指针

双指针

#resource / algorithm #type / concept #status / seed #algo / two-pointers

[!info] related notes 两数之和2 滑动窗口 [[binary-search-basics|二分查找基础]]

双指针

本质是利用数据的单调性(Monotonicity)来规避冗余计算——当一个指针的移动能确定地排除一批候选答案时,复杂度就从 $O(n^2)$ 降到 $O(n)$。

分类

1. 对撞指针(Opposite Direction)

两端向中间收缩,适用于有序数组上的配对问题。

def two_sum_sorted(arr, target):
    lo, hi = 0, len(arr) - 1
    while lo < hi:
        s = arr[lo] + arr[hi]
        if s == target:
            return [lo, hi]
        elif s < target:
            lo += 1      # 排除 arr[lo] 与 arr[lo+1..hi] 的所有配对
        else:
            hi -= 1      # 排除 arr[hi] 与 arr[lo..hi-1] 的所有配对
    return []

2. 同向指针(Same Direction / Fast-Slow)

两个指针同向移动,通常一个快一个慢,适用于去重、分区、链表环检测等。

def remove_duplicates(nums):
    """原地去重,返回新长度"""
    slow = 0
    for fast in range(1, len(nums)):
        if nums[fast] != nums[slow]:
            slow += 1
            nums[slow] = nums[fast]
    return slow + 1

3. 滑动窗口(Sliding Window)

本质是同向双指针的特化:leftright 维护一个满足条件的窗口。参见 滑动窗口

常见模式

模式指针类型典型题
两数之和(有序)对撞LeetCode 167
三数之和排序 + 对撞LeetCode 15
盛最多水的容器对撞LeetCode 11
回文判断对撞LeetCode 125
移除元素同向LeetCode 27
合并有序数组同向(从后往前)LeetCode 88
链表环检测快慢指针LeetCode 141

关键直觉

  • 有序是使用对撞指针的前提——排序预处理 $O(n \log n)$ 常能换来 $O(n)$ 的主过程。
  • 同向指针的核心是”慢指针维护已处理区,快指针探索未知区”。
  • 每次移动指针都应确定性地排除至少一个元素,否则退化为暴力。

相关笔记

创建于 2025/1/1 更新于 2026/5/27