什么情况下可以用双指针方法
数据特征(必要条件)
- 数据结构是有序的数组 / 字符串(最核心特征):左右指针的核心是'通过指针移动调整值的大小 / 满足匹配条件',有序性是指针移动有明确方向的前提;
- 数据结构是线性的、可通过下标 / 索引访问两端(数组、字符串、双链表):左右指针需要从'两端向中间'移动,无法访问两端的结构(如单链表)不适合。
问题目标(充分条件)
问题要求在数据中找「一对 / 一组元素」满足以下特征之一:
- 数值类:两数 / 三数之和、目标差值、最接近目标值;
- 匹配类:回文验证、对称判断、字符匹配;
- 操作类:反转数组 / 字符串、移除指定元素(有序场景)、分区(如快速排序的 partition)。
不适用情况
1. 数据无序且无法排序
比如'两数之和(无序数组)':
- 若题目要求返回原始下标,排序会打乱下标,此时无法用左右指针(只能用哈希表);
- 核心原因:排序破坏了问题的约束条件,左右指针的有序前提消失。
2. 数据结构无法访问两端
比如'单链表的回文验证':
- 单链表只能从头部遍历,无法直接访问尾部,无法初始化右指针;
- 替代方案:先用快慢指针找中点,再反转后半段链表,再用双指针比较(但已不是纯左右指针)。
3. 问题目标是'全局遍历'而非'两端匹配'
比如'数组中找最长递增子序列':
- 问题目标是找递增序列,无'两端向中间'的匹配逻辑,左右指针无移动方向;
- 核心原因:问题不依赖'两端值的比较',无法通过指针移动缩小问题范围。
移动零
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意,必须在不复制数组的情况下原地对数组进行操作。
示例 1:
输入: nums = [0,1,0,3,12] 输出: [1,3,12,0,0]
示例 2:
输入: nums = [0] 输出: [0]
思路:
- 让左右指针从起点开始,当右指针遇到非零数时,两个指针的值交换
- 左指针的左边都是非零数
- 右指针的左边至左指针都为零
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
n = len(nums)
left = right = 0
while right < n:
if nums[right] != 0:
nums[left], nums[right] = nums[right], nums[left]
left +=
right +=
nums


