双指针不是一个固定模板,而是一种减少重复搜索的思路:让两个位置按照条件有序移动,用一次线性扫描代替嵌套循环。理解“为什么移动这一侧”比记住代码更重要。
相向指针:利用单调性
在有序数组中寻找和为目标值的两个数时,左右指针分别从两端开始。当前和偏小就移动左指针,偏大就移动右指针,因为数组的有序性保证了这次移动不会错过可能的答案。
def two_sum_sorted(nums, target):
left, right = 0, len(nums) - 1
while left < right:
total = nums[left] + nums[right]
if total == target:
return left, right
if total < target:
left += 1
else:
right -= 1
return None
快慢指针:维护有效区间
原地删除重复元素时,慢指针指向有效结果的末尾,快指针负责探索新元素。快指针发现不同值后,再把它写到慢指针的下一个位置。整个过程中,区间 [0, slow] 始终满足题目要求。
边界比模板更重要
动手前应明确循环不变量、指针可取范围,以及指针相遇时是否还需要处理。尤其要区分 left < right 和 left <= right,它们代表是否允许单个元素成为候选。
写在最后
遇到数组或字符串问题时,可以先问:数据是否有序?窗口是否会单调扩张或收缩?能否让已经排除的区间永不回头?如果答案是肯定的,双指针通常值得一试。