← [ BACK_TO_NOTES ]

双指针

用两个位置维护搜索边界或已处理区域,按不变量移动指针,避免重复扫描。

#dev #algorithm #concept #growing #two-pointers

[!info] related notes 两数之和2 滑动窗口 二分查找

双指针

双指针用两个位置维护搜索边界或已处理区域。移动规则必须保持对应不变量:有序配对可以排除候选区间,原地去重维护已处理前缀,链表环检测则利用不同步速。若两个指针总共只移动 O(n) 次且每步更新为 O(1),主过程就是 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):
    """非递减数组原地去重,返回新长度"""
    if not nums:
        return 0
    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)

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

常见模式

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

关键直觉

  • 有序是上面数值配对时安全排除候选的前提;回文检查、盛水容器等对撞指针使用不同的不变量,并不要求数组按值排序。排序预处理后再线性扫描的总复杂度仍为 $O(n \log n)$。
  • 同向指针的核心是”慢指针维护已处理区,快指针探索未知区”。
  • 必须说明每次移动为何安全以及何时终止;指针数量本身不能保证线性复杂度。

相关笔记

创建于 2025/1/1 更新于 2026/10/6
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本