双指针
本节目标
用同向、相向与排序后双指针维护有效区间、候选边界和去重规则。
双指针不是固定的两行模板,而是用两个位置把数组分成已处理区间、未处理区间和仍可能成为答案的候选区间。先明确每根指针维护什么,再证明每次移动都没有丢掉答案。
识别信号
题目要求原地删除、压缩或保持相对顺序时,通常让读指针扫描输入、写指针维护有效前缀。题目在两端选择边界、比较和或面积时,通常从两端相向收缩。若需要找出满足和关系的多个组合,先排序再使用相向指针,能够同时控制搜索方向和重复答案。
问题模型与核心不变量
同向扫描中,[0, write) 始终是已确认的有效前缀,[read, n) 尚未处理。相向扫描中,[left, right] 是还可能参与最优解的候选区间;移动一侧前必须能说明该侧参与的其他组合也不会更好。排序后双指针还要保持:固定值以前的重复值已跳过,左右指针之间是尚未判断的有序候选。
通用模板
同向:read 扫描每个元素;满足保留条件时写到 nums[write],再移动 write。
相向:计算当前候选;根据单调性排除一侧边界,再移动对应指针。
排序组合:固定一个位置,left/right 相向移动;命中后跳过两端重复值。
模板中的“保留条件”和“排除规则”才是题目差异所在。不能只因为看见两个下标就机械套用。
模板变体
《移除元素》《删除有序数组中的重复项》和《移动零》都用同向指针,但写入条件分别来自过滤、有序性和稳定压缩。《盛最多水的容器》按较短边相向移动;《三数之和》先排序,固定一个数后把两数之和的比较转成指针移动。
母题序列
按必学顺序完成下列五题:
- 移除元素(必学):建立“有效前缀”这一最小原地扫描模型。
- 删除有序数组中的重复项(必学):利用有序性决定是否写入。
- 移动零(必学):稳定压缩后统一补齐尾部。
- 盛最多水的容器(必学):证明较短边可以安全移动。
- 三数之和(必学):排序、相向搜索与去重协同工作。
常见误区
- 原地题返回
write后,把整个数组都当作有效答案,忽略了只有有效前缀有定义。 - 同向压缩时从写入位置继续读,覆盖了尚未处理的元素。
- 容器题移动较高边,无法排除更优解,搜索空间不会正确缩小。
- 三数之和只跳过固定值的重复项,忘记在命中后跳过左右端重复值。
- 为了保留输入顺序而不排序三数之和,失去利用和的单调性移动指针的依据。
迁移方向
滑动窗口把同向指针扩展为一个持续维护状态的区间;前缀和题则常用历史信息替代左指针的逐步收缩。进一步的双向贡献模型见接雨水:它用两端最高值确定当前较低侧的贡献。