双指针
双指针本质是对当前位置或当前范围的一种表示,通过两个变量表示下标来模拟对位置的指向,通过移动这两个变量来控制位置或范围的变化。它的核心思想在于让两个指针在序列上以特定规律移动,从而将原本需要多重循环的暴力解法优化为更高效率的算法。
双指针的最大优势在于其卓越的性能。它通过单次线性遍历和巧妙的指针移动,避免了不必要的嵌套循环,成功将许多问题的时间复杂度从 O(n²) 优化至 O(n)。这种技巧不仅提升了效率,更让代码逻辑变得清晰直观。
双指针主要模拟了考虑和选择的过程,往往与枚举、贪心的思想结合使用,使用前有时需要先进行排序。
1. 同数组指针
1.1 同向双指针
同数组中,两个指针分别指向两个位置,并且两个指针移动方向都相同(一般是都从前向后),此时这两个位置作为边界形成的范围就是当前选择的范围。

这个范围的长度如果是固定的,就视为一个滑动窗口,往往用于解决连续子数组问题,还可以结合前缀和减少重复计算,结合单调队列快速获得区间极值。


如果问题是找出数组中符合要求的最长连续长度,此时双指针表示范围的长度是不固定的,就需要根据情况调整左右指针移动来实现范围长度的变化。这就是尺取,结合贪心的思想,考虑对前面位置的放弃和后续位置的选取,来调整指针的移动。

当我们进行数组内的范围选择时,就可以采用同向双指针的方法描述当前范围,复杂度会低于嵌套循环。同向双指针的情况下,指针模拟了选择范围的边界,当我们需要改变边界位置来改变选择范围时,就通过移动指针指向位置来模拟边界的变化,从而实现范围的改变。此类问题中需要关注指针的移动策略以及所需内容的记录,以便后续的计算。


练习题
- 连续自然数和
- 最值问题
- 心算挑战
- 小A爱读书
- Cow Lineup S
- 逛画展
- 唯一的雪花
- [GESP202406 四级] 宝箱
- 纪念品分组
- 吃糖果
- 木桶原理
- 寻找舞伴
- 我要成为出题者!
- 晚会准备
- [GESP202312 四级] 田忌赛马
- 闪耀的宝石
1.2 碰撞双指针
双指针的初始位置在数组两端,表示两种极端的情况。双指针会向中间移动,直至相遇为止。这种情况我们称为碰撞双指针。


比如当我们考虑此时选择最小元素能够使得结果最优,那么我们就会用掉这个最小的元素。使用之后,我们继续重复这样的一个考虑过程,但代表最小元素的位置发生了改变,应该往后移动一个位置,继续指向仍在考虑范围内的最小元素。

而当我们选择最大元素时,例如组队问题中我们发现最大元素只能单独组队,那么我们就会用掉这个最大的元素。使用之后,代表最大元素的位置同样发生了改变,但此时考虑范围内的最大元素位置是往前移动了一个位置。我们继续重复这样的一个考虑过程,始终让右指针指向考虑范围内的最大元素。

当左右指针相遇在同一个位置时,此时还剩下最后一个需要考虑的元素。当左右指针的相对左右出现错误时,范围内此时已经没有剩余元素,应该结束双指针操作。

此类问题通常会与贪心结合,要用贪心的思想考虑指针的移动情况,什么时候左指针右移,什么时候右指针左移,什么时候应该各动一次,这些都需要根据对题目信息的分析来确定应该模拟实际的选择与变化。比如此时应该是消耗掉最小的纪念品,那么当前最小的纪念品位置应该移动到下一个位置。当前想使用掉最大的纪念品,那么当前最大的纪念品就会移动到前一个位置。如果同时使用掉最大的和最小的纪念品,那么此时代表最大和最小纪念品的位置都应该相应地进行移动,移动到还需要继续考虑的位置。此类同数组内不同位置需要同时考虑的过程都可以使用碰撞双指针来简单实现过程的模拟。
练习题
2. 双数组指针
两个指针指向不同的数组,分别表示不同的概念,但都指向位置都表示当前考虑的位置,指针的移动都表示考虑位置的移动,一般是从前往后的同向移动。双数组指针分成两种情况,一种是一个指针一直动另一个指针看情况动,一种是两个指针都看情况动。

一个指针一直动的情况例如匹配,认为两数组中的内容匹配不上,那么一定有一个内容是无法被匹配的,就应该直接放弃。
两个指针都看情况动例如田忌赛马,两个数组当前考虑的位置使用完就都轮到下一个了,就一起往后移动。也可能还有更多需要考虑的内容,可能导致当前的两个指针都不变化,其他的信息发生改变,可以类比为更多的指针。
当我们需要同时考虑多个信息时,我们就会考虑用双数组指针分别表示各个信息的情况,然后通过指针的移动模拟分析选择的过程来得到最终的结果。
练习题
3. 两遍双指针
两遍双指针主要需要考虑指针不同意义,比如分别维护左边和右边最长的区间长。此类题目需要考虑两遍中指针的不同含义,以及移动过程中的区别,考虑变量意义和贪心策略是更关键的部分。




两遍双指针主要是根据情况来使用,并不是一种普遍的思想或技巧。每次双指针只是单纯地考虑当前所需的内容,但有时我们可能需要分别使用双指针的技巧去求得一些不同含义或不同情况的结果,此时就形成了两遍双指针的情况。
练习题

01
朴实无华的瑟提
普及-
--
练习
02
N - 8进制回文数
普及-
--
练习
03
共享食物
普及-
--
练习
04
表演配对
普及-
--
练习
05
纪念品分组
普及-
--
练习
06
促销活动
普及-
--
练习
07
最值问题
入门
--
练习
08
赛题挑选
普及-
--
练习
09
心算挑战
普及-
--
练习
10
二路归并
入门
--
练习
11
学习计划
普及-
--
练习
12
糖果店的购物挑战
普及-
--
练习
13
[USACO011NOV] Cow Lineup S
普及/提高-
--
练习
14
图书馆借书挑战
普及-
--
练习
15
魔法飞弹收集
普及-
--
练习
16
水瓶挑战
普及-
--
练习
17
参观博物馆
普及-
--
练习
18
[GESP202312 四级] 田忌赛马
普及-
--
练习
19
[GESP202406 四级] 宝箱
普及-
--
练习
20
收藏展示
普及/提高-
--
练习