news 2026/5/1 9:54:13

双指针专题(三):去重的艺术——「三数之和」

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
双指针专题(三):去重的艺术——「三数之和」

哈喽各位,我是前端小L。

场景想象:

给你一个数组 [-1, 0, 1, 2, -1, -4]。

我们要找出所有和为 0 的三个数 [a, b, c]。

  • 我们可以找到[-1, 0, 1]

  • 还可以找到[-1, 2, -1](排序后是[-1, -1, 2])。

  • 难点:数组里有两个-1,如果我们不加控制,代码很可能会把第一个-1开头的[-1, 0, 1]算一次,再把第二个-1开头的[-1, 0, 1]又算一次。这就是重复

力扣 15. 三数之和

https://leetcode.cn/problems/3sum/

题目分析:

  • 输入:整数数组nums

  • 输出:所有和为 0 的不重复三元组。

  • 复杂度要求:暴力法是 $O(N^3)$,肯定超时。我们需要优化到$O(N^2)$

核心思维:排序 + 固定一个,找另外两个

既然双指针擅长解决“两数之和”,那我们能不能把“三数之和”降维打击?

策略:

  1. 先排序:这是去重和使用双指针的前提!(例如[-4, -1, -1, 0, 1, 2])。

  2. 遍历固定位 (i):我们遍历数组,固定第一个数nums[i]

  3. 双指针找两数:剩下的问题就变成了——“在i后面的数组中,找到两个数LeftRight,使得nums[Left] + nums[Right] = -nums[i]”。

去重逻辑(最关键):

  1. 外层去重(针对 i):

    如果 nums[i] === nums[i-1],说明这个数刚才已经作为“第一个数”处理过了,再处理一遍肯定会得到一样的结果。跳过!

  2. 内层去重(针对 Left 和 Right):

    当我们找到了一个合法的组合后,如果 nums[Left] === nums[Left+1],说明下一个数还是一样,会导致结果重复。跳过! 右边同理。

算法流程 (JavaScript)

  1. 排序nums.sort((a, b) => a - b)

  2. 外层循环i0n-2

    • 如果nums[i] > 0:因为已经排序,第一个数大于0,后面不可能凑出 0 了,直接break

    • 去重if (i > 0 && nums[i] === nums[i - 1]) continue;

    • 双指针启动L = i + 1,R = n - 1

      • 计算sum = nums[i] + nums[L] + nums[R]

      • sum > 0:数太大了,R往左移。

      • sum < 0:数太小了,L往右移。

      • sum === 0

        • 记录答案res.push([nums[i], nums[L], nums[R]])

        • 内层去重while (L < R && nums[L] === nums[L+1]) L++;(跳过重复的L)

        • 内层去重while (L < R && nums[R] === nums[R-1]) R--;(跳过重复的R)

        • 双双移动L++,R--(寻找下一组)。

代码实现

JavaScript

/** * @param {number[]} nums * @return {number[][]} */ var threeSum = function(nums) { const result = []; // 1. 必须排序 nums.sort((a, b) => a - b); const len = nums.length; for (let i = 0; i < len; i++) { // 剪枝:如果第一个数已经大于0,后面都是正数,不可能凑成0 if (nums[i] > 0) break; // 2. 外层去重:如果我们遇到了和上一次一样的数字,跳过 // 注意是 i > 0,防止 i-1 越界 if (i > 0 && nums[i] === nums[i - 1]) continue; let L = i + 1; let R = len - 1; while (L < R) { const sum = nums[i] + nums[L] + nums[R]; if (sum === 0) { // 找到一组,加入结果 result.push([nums[i], nums[L], nums[R]]); // 3. 内层去重:找到答案后,看看左右指针旁边是不是有重复的 // 如果有,一直跳过,直到指向最后一个重复元素的下一位 while (L < R && nums[L] === nums[L + 1]) L++; while (L < R && nums[R] === nums[R - 1]) R--; // 找到答案后,两个指针都要收缩 L++; R--; } else if (sum < 0) { // 和太小,左指针右移变大 L++; } else { // sum > 0 // 和太大,右指针左移变小 R--; } } } return result; };

深度辨析:为什么去重是nums[i] === nums[i-1]

很多同学会纠结:是判断nums[i] == nums[i-1]还是nums[i] == nums[i+1]

  • 情况 A (nums[i] == nums[i-1]):

    比如 [-1, -1, 2]。

    • i=0(第一个 -1):处理一遍,找到了[-1, -1, 2]

    • i=1(第二个 -1):我们回头看,发现前一个也是 -1。如果我们再处理,就会重复寻找。所以跳过。

    • 这是正确的逻辑:只要我前面那个“长得跟我一样”的兄弟已经处理过了,我就不用再处理了。

  • 情况 B (nums[i] == nums[i+1]):

    如果我们判断的是后一个。

    • i=0(第一个 -1):发现后面也是 -1,直接跳过?

    • 错!这样你就漏掉了[-1, -1, 2]这一组情况(这组情况需要用到两个 -1)。

    • 结论:我们去重的是“作为第一个加数的重复”,而不是禁止三元组内部有重复数字。

总结

这道题是双指针的里程碑。

掌握了它,你就掌握了 “排序 + 降维 + 双指针夹逼 + 细致去重” 的完整套路。


下一题预告:四数之和

如果面试官觉得三数之和太简单,可能会随手丢给你一道LC 18. 四数之和

  • 题目:找到a + b + c + d = target

  • 思路:套娃

    • 三数之和是:固定i,算两数之和。

    • 四数之和是:固定k,再固定i,算两数之和。

  • 难点:多了一层循环,也就多了一层剪枝去重的逻辑。

准备好再加一层循环了吗?下期见!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/28 9:42:13

RK3588平台下aarch64与设备树交互机制深度解析

RK3588平台下aarch64与设备树交互机制深度解析从一个启动问题说起&#xff1a;为什么我的外设没被识别&#xff1f;在调试一块全新的RK3588开发板时&#xff0c;你是否遇到过这样的场景&#xff1a;内核顺利启动&#xff0c;串口输出正常&#xff0c;但某个关键外设——比如SPI…

作者头像 李华
网站建设 2026/5/1 9:43:38

AQLM极低比特量化:适用于边缘设备的部署方案

AQLM极低比特量化&#xff1a;适用于边缘设备的部署方案 在消费级笔记本上运行70亿参数的大模型&#xff0c;听起来像是天方夜谭&#xff1f;但在今天&#xff0c;这已经不是幻想。随着AQLM&#xff08;Adaptive Quantization for Large Models&#xff09;等极低比特量化技术的…

作者头像 李华
网站建设 2026/4/29 9:42:22

GPTQ训练支持:逐层量化与误差补偿机制解析

GPTQ训练支持&#xff1a;逐层量化与误差补偿机制解析 在大模型落地日益迫切的今天&#xff0c;一个70亿参数的语言模型动辄需要数十GB显存才能运行&#xff0c;这让许多开发者望而却步。即便拥有A100这样的高端卡&#xff0c;部署多个服务实例依然捉襟见肘。有没有可能让Qwen-…

作者头像 李华
网站建设 2026/4/18 6:48:15

java计算机毕业设计徐福记智能物流园区管理系统 高校毕业设计:基于SpringBoot的智慧仓储物流综合管控平台 本科项目实战:JavaWeb 智能物流园区作业调度与可视化系统

计算机毕业设计徐福记智能物流园区管理系统7j57l9&#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。零食巨头徐福记每天上千辆货车进出园区&#xff0c;人工登记、手工派单、纸质出…

作者头像 李华
网站建设 2026/4/28 11:30:15

支持100+评测数据集:学术研究与工业落地双重保障

支持100评测数据集&#xff1a;学术研究与工业落地双重保障 在大模型技术飞速演进的今天&#xff0c;一个现实问题日益凸显&#xff1a;尽管LLaMA、Qwen等主流模型在自然语言理解、视觉推理等领域展现出惊人能力&#xff0c;但真正将其从实验室推向生产环境时&#xff0c;开发…

作者头像 李华
网站建设 2026/5/1 5:48:58

OpenMP 5.3任务模型升级详解:从入门到精通的8个关键知识点

第一章&#xff1a;OpenMP 5.3任务模型核心演进OpenMP 5.3 在任务并行模型方面引入了多项关键改进&#xff0c;显著增强了任务调度的灵活性与性能控制能力。这些演进主要集中在任务依赖表达的增强、任务取消机制的标准化以及任务组语义的细化&#xff0c;为复杂并行应用提供了更…

作者头像 李华