双指针

8 阅读2分钟

双指针(Two Pointers) 是编程里非常经典、也非常实用的一种技巧,尤其在数组、字符串、链表这类线性结构中出镜率超高。

循环的本质,就是用一个“指针”变量,按照某种规律(顺序、条件)移动,依次访问或处理一系列数据。

但是当循环中出现循环的嵌套时,时间复杂度就会指数上升,暴力解决不是不可以,但是却不能一直如此

一、什么是双指针?

核心思想一句话:

用两个指针(索引 / 引用)在同一个数据结构上协同移动,减少不必要的重复遍历。

相比一个指针从头扫到尾,双指针往往能把

  • 时间复杂度从 O(n²) 降到 O(n)
  • 或者让逻辑更清晰、代码更优雅

二、常见的双指针类型

1.对撞指针(左右指针)

特点:

  • 一个指针从左边开始
  • 一个指针从右边开始
  • 不断向中间靠拢

典型场景:

  • 有序数组
  • 回文判断
  • 两数之和(已排序)

2.快慢指针(Fast & Slow)

特点:

  • 两个指针同向移动
  • 速度不同(1步 / 2步)

典型场景:

  • 链表是否有环
  • 找链表中点
  • 删除倒数第 N 个节点

2.滑动窗口(本质也是双指针)

特点:

  • 两个指针维护一个区间 [left, right)
  • 窗口可扩张 / 收缩

典型场景:

  • 子数组 / 子串问题
  • 连续区间最大值、最小值
  • 满足某种条件的最短 / 最长区间

三、什么时候该想到双指针?

你可以用这几个触发关键词来判断

  • 有序数组
  • 连续区间 / 子数组 / 子串
  • 需要降低时间复杂度
  • 不能用额外空间(O(1) 空间)
  • 链表相关问题

四、注意事项

  • 注意边界条件:要小心处理数组或链表为空、只有一个元素等边界情况,防止数组越界;需要明确定义循环何时结束,通常是 left < right 或 fast != nil