双指针法解三数之和为零,核心是排序后固定一数、双指针找补,通过升序排列实现单调性与去重,外层跳过重复首元及正数剪枝,内层双指针收缩并同步跳过左右重复值。

双指针法解决三数之和为零问题,核心是“排序 + 固定一数 + 双指针找补”,关键不在暴力枚举,而在利用有序性高效收缩搜索空间,并通过跳过重复值天然去重。
先排序,建立单调性和去重基础
对原数组升序排序,比如 [-1, 0, 1, 2, -1, -4] 变成 [-4, -1, -1, 0, 1, 2]。这一步带来两个好处:一是让相同元素相邻,方便后续跳过;二是保证左指针往右走和右指针往左走时,和值单调变化,从而能明确移动方向。
外层遍历固定第一个数(a),并做剪枝
用索引 i 从头开始遍历,把 nums[i] 当作三元组的第一个数:
- 若 i > 0 且 nums[i] == nums[i-1],直接跳过,避免以相同值重复开头
- 若 nums[i] > 0,可立即终止循环——因为数组已排序,后面所有数都 ≥ nums[i],三个正数之和不可能为 0
- 目标值设为 target = -nums[i],接下来只需在 i+1 到末尾 区间内找两数之和等于 target
内层双指针找 b 和 c(两数之和子问题)
设左指针 left = i+1,右指针 right = n-1,循环条件为 left :
- 计算当前和 sum = nums[left] + nums[right]
- 若 sum == target:找到一组解 [nums[i], nums[left], nums[right]],存入结果;然后同时移动两个指针,并跳过所有与刚用过的值相同的元素(while(left ,同理处理 right)
- 若 sum :和太小,需增大,left++
- 若 sum > target:和太大,需减小,right--
去重逻辑落在三个位置,缺一不可
重复三元组只可能来自以下三种情况,每种都需主动跳过:
- 首元素重复:i 层循环中,连续相同值的 nums[i] 只处理一次
- 左元素重复:找到解后,left 向右跳过所有相同值,确保下一次取的是新数字
- 右元素重复:同理,right 向左跳过所有相同值











