Algorithm
双指针与滑动窗口:把重复枚举变成一次扫描
双指针不是一道具体算法题,而是一种减少重复工作的方式。两个下标按照规则移动,把原本可能需要两层循环的问题压缩成线性扫描。
相向双指针
在有序数组中寻找两数之和,可以让 left 指向开头、right 指向结尾:和太小就移动 left,和太大就移动 right。
while (left < right) {
int sum = nums[left] + nums[right];
if (sum == target) return true;
if (sum < target) left++;
else right--;
}
它成立的关键是数组有序。每次比较都能排除一批不可能答案,时间复杂度从 O(n²) 降到 O(n)。
快慢指针
快慢指针常用于链表环检测、寻找中点、原地删除重复元素。快指针负责探索,慢指针维护已经处理完成的边界。
写代码前要说明两个指针各自代表什么。例如原地去重中,slow 指向最后一个有效元素,fast 扫描尚未处理的数据。这个“不变量”比模板本身更重要。
滑动窗口
滑动窗口是同向双指针的一种形式,适合处理连续子数组或子串:右指针扩展窗口,条件不满足时左指针收缩。
right 扩展并加入新元素
→ 更新窗口状态
→ while 条件不满足,移动 left
→ 使用当前窗口更新答案
窗口状态可以是字符频次、元素总和、不同元素数量等。最常见的错误是收缩条件写反、更新答案的时机不对,或 left 移动后忘记同步更新统计值。
我的解题检查表
- 题目是否要求连续区间,或输入是否有序?
- left、right 分别表示什么?
- 窗口始终保持的条件是什么?
- 什么时候扩展、什么时候收缩?
- 答案在收缩前还是收缩后更新?
只要不变量定义清楚,双指针就不再是需要死记的模板,而是可以现场推导的扫描过程。