永不忘算法:三数之和的“双指针”魔法

算法修炼十九层:从数据结构到动态规划的体系化进阶指南 算法与数据结构是计算机科学的核心基础,它们共同构成了高效解决计算问题的思维框架。其原理在于通过精心设计的‘容器’(数据结构)来组织数据,并运用特定的‘步骤’(算法)来处理数据,从而在时间与空间效率上达到最优平衡。掌握这套思维的价值在于,它能将复杂问题模块化、清晰化,是开发高性能软件、通过技术面试、进行系统优化的基石。无论是构建搜索引擎、推荐系统,还是开发数据库、操作系统,扎实的算法功底都不可或缺。本文以程序员熟悉的‘修炼’为隐喻,系统性地梳理了从数组、链表、哈希表等基础数据结构,到排序、二分查找、双指针、B 阅读详情

永不忘算法:三数之和的“双指针”魔法

大家好!今天我们要解决一道非常经典的算法题——三数之和。这道题之所以经典,是因为它不仅考察逻辑,还考察我们如何“偷懒”(优化效率)。为了让你永远记住它,我们不谈枯燥的定义,直接用生活中的例子来模拟,最后再配合代码实现。

一、 题目是什么?

想象一下,你面前有一堆乱七八糟的数字卡片,比如 [-1, 0, 1, 2, -1, -4]。
你的任务是:从这些卡片中找出所有的“三人组”,要求这三个数字加起来正好等于 0。

注意:

  1. 不能重复找同一个三人组(比如找到了 (-1, 0, 1),下次就不能再找 (-1, 0, 1) 了)。
  2. 三人组里的数字必须是不同位置的卡片(虽然数字可以一样,但位置不能重复)。

二、 为什么暴力解法很“笨”?

最笨的方法是什么?是“三重循环”。
也就是:先拿第一个数,去遍历所有第二个数,再针对每个第二个数,去遍历所有第三个数。这就像是你去超市买东西,把货架上的每一样商品都拿起来看一遍,效率极低。如果数字很多(比如几千个),这种方法算到天黑都算不出来。

我们要学的,是聪明的“双指针”法!

三、 魔法第一步:排排队(排序)

在开始找之前,我们必须先做一件事:把这些数字从小到大排好序。
排序后,上面的例子变成了:[-4, -1, -1, 0, 1, 2]。

为什么要排序?

  1. 方便去重:数字排在一起,一眼就能看出有没有重复。
  2. 利用大小关系:这是双指针法的核心!排好序后,左边的数字小,右边的数字大。如果我们想找和为 0 的组合,就可以根据当前的大小来决定是往左找还是往右找。

四、 核心魔法:锁定一个,移动两个

我们可以把问题简化:先确定第一个数,然后去找另外两个数,让这三个数加起来等于 0。

这就好比我们要组一个三人足球队:

  1. 队长(第一个数):我们从左到右依次选。
  2. 队员(另外两个数):我们用双指针来找。

图解双指针战术

假设我们选定了队长是 -4(数组第一个数)。此时,我们需要另外两个数加起来等于 4(因为 -4 + 4 = 0)。

我们在队长右边的所有数字里,设置两个“指头”:

  • 左指针(L):指向剩余数字里最小的那个(最左边)。
  • 右指针(R):指向剩余数字里最大的那个(最右边)。

现在的状态是:

  • 队长:-4
  • 剩余数组段:[-1, -1, 0, 1, 2]
  • L 指向 -1,R 指向 2。

战术规则:

  1. 计算三数之和:-4 (队长) + (-1) (L) + 2 (R) = -3。
  2. 判断:
    • 结果是 -3,比目标 0 小了!
    • 怎么办? 我们需要让结果变大一点。
    • 行动:因为数组是排好序的,L 指针左边的数更小(没用),R 指针右边的数更大(已经没了)。唯一的办法是把 L 指针往右挪,换一个稍微大一点的数。
  3. 移动 L:L 指向下一个 -1。
  4. 再次计算:-4 + (-1) + 2 = -3。还是太小,继续挪 L。
  5. L 指向 0。计算:-4 + 0 + 2 = -2。还是小,挪 L。
  6. L 指向 1。计算:-4 + 1 + 2 = -1。还是小,挪 L。
  7. L 和 R 相遇了:说明在这个队长下,找不到合适的队员。换下一个队长!

换个队长试试:

现在队长换成数组第二个数:-1。
剩余数组段:[-1, 0, 1, 2]

  • L 指向 -1,R 指向 2。
  1. 计算:-1 (队长) + (-1) (L) + 2 (R) = 0。
  2. 判断:中了!正好是 0!
  3. 记录:把 [-1, -1, 2] 放进答案篮子。
  4. 下一步:既然找到了,L 和 R 都要往中间缩,继续找有没有其他可能。
    • 关键去重技巧:在移动 L 之前,先看一眼,下一个数字是不是还是 -1?如果是,直接跳过!因为刚才已经找过 -1 了,再找就重复了。这就像去食堂打饭,同一个菜不用打两份。

继续移动:

  • L 指向 0,R 指向 1。
  1. 计算:-1 (队长) + 0 + 1 = 0。
  2. 判断:又中了!
  3. 记录:把 [-1, 0, 1] 放进答案篮子。
  4. 移动:L 往右,R 往左。L 和 R 碰头了,结束。

五、 动画演示(脑补版)

为了让你更有画面感,请想象以下动画过程:

初始数组:[-4, -1, -1, 0, 1, 2]

【第一轮:队长 -4】
L(-1) ---------------------- R(2)
和太小!L 往右跳 -> 跳 -> 跳 -> 碰到 R,结束。

【第二轮:队长 -1】
L(-1) ------------------ R(2)
和为 0!找到 [-1, -1, 2]!
L 往右跳过重复 -> R 往左

L(0) ------------ R(1)
和为 0!找到 [-1, 0, 1]!
L 往右 -> 碰到 R,结束。

六、 代码实现(看注释就能懂)

把上面的逻辑翻译成 Java 代码,就是这样:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ThreeSum {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        
        // 第一步:排排队!从小到大
        Arrays.sort(nums);
        
        // 第二步:选队长(遍历数组)
        for (int i = 0; i < nums.length - 2; i++) {
            // 去重技巧 1:如果这个队长和上一个队长一样,跳过!
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }
            
            // 定义双指针
            int left = i + 1;         // 左指针:队长右边的那个人
            int right = nums.length - 1; // 右指针:队尾的那个人
            int target = -nums[i];    // 目标:我们需要另外两人加起来等于 -队长
            
            // 第三步:左右夹击
            while (left < right) {
                int sum = nums[left] + nums[right];
                
                if (sum == target) {
                    // 找到了!记下来
                    result.add(Arrays.asList(nums[i], nums[left], nums[right]));
                    
                    // 去重技巧 2:如果左指针下一个人还一样,直接跳过
                    while (left < right && nums[left] == nums[left + 1]) {
                        left++;
                    }
                    // 去重技巧 3:如果右指针下一个人还一样,直接跳过
                    while (left < right && nums[right] == nums[right - 1]) {
                        right--;
                    }
                    
                    // 同时收缩,寻找下一组
                    left++;
                    right--;
                } else if (sum < target) {
                    // 和太小了,说明左边的数太小,把左指针往右挪(换大一点的数)
                    left++;
                } else {
                    // 和太大了,说明右边的数太大,把右指针往左挪(换小一点的数)
                    right--;
                }
            }
        }
        return result;
    }
}

七、 总结:怎么保证永不忘?

记住这三个关键词,你就永远不会忘:

  1. 排序:这是双指针法的前提,没有排序就没有方向感。
  2. 定一移二:先定住第一个数,剩下的用两个指针从两头往中间凑。
  3. 去重:选队长时看前一个,移动指针时看下一个,只要数字一样就跳过。

这就是“三数之和”的奥秘。你学会了吗?


参考来源

 

在Kintex-7 FPGA上实现皮秒级时间测量:手把手教你搭建CARRY4进位链TDC(附源码与约束) 本文详细介绍了在Kintex-7 FPGA上利用CARRY4进位链实现皮秒级时间测量(TDC)的完整方案。从CARRY4的物理特性分析到硬件架构设计,再到校准方法与精度提升技巧,手把手教你构建测量精度达53ps的TDC系统,并附源码与约束文件,助力激光雷达、高能物理等精密计时应用开发。 阅读详情

相关推荐

拆解人形机器人:核心硬件与驱动系统

本文深入解析人形机器人的核心硬件系统,将其类比为"骨骼+肌肉+神经"的集成体。重点介绍了三大关键组件:驱动单元(无框力矩电机和空心杯电机)、传动单元(谐波减速器和行星滚柱丝杠)以及感知单元(力矩传感器、编码器和IMU)。文章指出一体化关节模组正成为行业趋势,能够实现更紧凑的结构和更高的可靠性。同时分析了硬件价值量分布,强调丝杠、电机等部件是当前技术高地和成本重心。最后指出随着技术进步,机器人价值将更多向"大脑"和"神经"转移。

小明的博客 1529

【优选算法篇】:双指针算法--开启高效编码的两把“魔法指针”,练习题演练

双指针算法最核心的用途是优化时间复杂度。原本两个指针有n2中组合,时间复杂度是O(n2)。而双指针算法通过运用单调性,使得指针只能单项移动,因此总的时间复杂度只有O(n)。,又称快慢指针算法,龟兔赛跑算法等,是一种在链表,数组,矩阵等数据结构中,通过设置两个指针,并通过特定的移动策略来遍历数据元素同时解决问题的编程技巧。

2301_82347435的博客 1826

Blender软件导出地形到Gazebo中

Blender软件导出地形到Gazebo中,并配置纹理、刚度、高度。

m0_70652514的博客 3376

【算法探秘】三数之和:数字海洋中的奇妙组合之旅

三数之和”问题,即给定一个整数数组和一个目标值,找出数组中所有和为目标值的三个不同元素的组合。这个问题考验着程序员对双指针法和排序技术的巧妙运用。

master_chenchen的博客 995

《最游记》游戏开发全栈指南:从源码解析到实战部署

本文提供了一份详尽的《最游记》游戏源码全栈开发指南。文章深入解析了这款3D玄幻网游的完整源码结构,涵盖客户端、服务端、引擎和工具链,并提供了从环境搭建、核心模块解析到实战修改与部署的完整流程。对于希望深入理解MMORPG架构的开发者而言,这份指南是宝贵的实战资源。

weixin_28363123的博客 71

时序数据库避坑指南:TDengine与IoTDB在车联网场景的7个关键对比

本文对比了时序数据库TDengine与IoTDB在车联网场景下的7个关键差异,包括数据模型设计、边缘-云端协同能力、车规级函数库、存储压缩算法等。通过真实案例和性能测试,帮助企业在新能源汽车大数据处理中选择合适的时序数据库,优化存储成本和实时告警性能。

rust6ferris的博客 452

双指针魔法:滑动窗口与快慢指针

本文系统梳理了双指针算法的三大范式:滑动窗口、快慢指针和对撞指针。滑动窗口通过同向移动的两个指针维护连续区间,适用于子串/子数组问题,其模板包含扩张、收缩和更新答案三个步骤;快慢指针利用速度差解决链表判环、找中点等问题;对撞指针则从两端向中间逼近处理有序数组问题。文章详细解析了各类双指针的工作原理、代码模板及适用场景,强调通过复用信息降低复杂度。掌握这些范式能有效提升算法解题效率,其思想也可应用于工程实践中的流式数据处理等问题。

程序猿老樊的博客 439

零基础搭建本地AI绘画环境:Stable Diffusion 3.5保姆级安装教程(含中文优化方案)

本文提供零基础搭建本地AI绘画环境的详细教程,重点介绍Stable Diffusion 3.5的安装与中文优化方案。从硬件配置检查到软件依赖安装,再到核心组件配置与中文语义增强,教程涵盖全流程操作指南,帮助用户快速掌握AI文生图模型的本地部署技巧,提升创作效率。

weixin_30752699的博客 312

Hot100_LeetCode 15 | 三数之和(3Sum)

排序 + 双指针的配合使用去重逻辑的理解和编写(非常容易出错)合理剪枝,提升性能。

qq_62041987的博客 686

SFT看这一篇就够了!万字长文:监督微调(Supervised Fine-Tuning, SFT)技术全解析【从理论到实战】

大家好,我是大 F,深耕AI算法十余年,互联网大厂技术岗。分享AI算法干货、技术心得。欢迎关注,一起探索技术的无限可能!

大F子的智能小课 711

即插即用系列(代码实践)| 2025 Strip R-CNN:大尺寸条形卷积——遥感目标检测新SOTA,专治细长目标(桥梁、船只)

摘要: 论文《Strip R-CNN: Large Strip Convolution for Remote Sensing Object Detection》针对遥感图像中细长目标(如桥梁、道路)检测难题,提出创新性解决方案。通过设计StripBlock模块,将传统方形卷积核替换为大尺寸条形卷积(水平1×19与垂直19×1组合),有效捕获长距离空间特征,同时减少背景噪声。结合CenterPooling增强目标中心定位,该模块可即插即用至现有网络,显著提升遥感检测任务(如DOTA数据集)的精度。代码已开源,

分享顶会顶刊论文即插即用模块 189

【算法日记】阶段大满贯:搞透大厂必考的两大核心套路(哈希表 & 双指针)

刷算法题绝对不是死记硬背代码,而是要培养“嗅觉”:闻到“查找、匹配、去重、$O(N)$”的味道 ➡️掏出哈希表。闻到“原地操作、组合求和、有序数组”的味道 ➡️掏出双指针。掌握了这两大件兵器,大厂面试 50% 以上的手撕代码关,你都可以横着走了!我们下一关见!🚀。

aqiu111111的博客 162

Android 13 灭屏音乐播放问题解决与优化建议

通过在中增加对音乐播放状态的检测,我们成功解决了客户应用在灭屏状态下音乐播放被中断的问题。

m0_60898338的博客 1157

算法技巧提升:从 “暴力破解” 到 “优雅解题” 的进阶之路

本文系统性地总结了提升算法能力的核心方法论,提出"思维方式+工具库+实战经验"的三维提升路径。在思维方式层面,强调拆解问题、抽象模型和逆向思考三大基本功;工具库部分详细解析双指针、哈希表、动态规划等10种高频算法技巧的应用场景和实现要点;实战环节则提供从基础刷题到面试模拟的渐进式训练策略。文章特别指出算法能力的提升是"理解-练习-复盘"的循环过程,建议优先掌握核心技巧而非追求偏题怪题,通过刻意练习将解题思路从"随机尝试"转化为"系统思考&

c23856的博客 190

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

两数之和:从暴力到优雅的算法演进

作为《GO兔算个球》专栏开篇,以LeetCode经典题目为切入点,展示算法优化的完整思维过程。文章从青铜解法(O(n²)双重循环)讲起,剖析其在大数据量下的性能瓶颈;揭示白银解法(排序+双指针)的致命缺陷——无法保留原始下标;最终呈现黄金解法(哈希表)的空间换时间魔法,实现O(n)时间复杂度。特别强调Go语言实现细节:map先查后存避免重复使用、动态扩容优化、并发安全考量等实战技巧。通过"兔子跑步"比喻复杂度,代码注释融入幽默吐槽,让初中级工程师轻松掌握算法优化的权衡思维,理解从"能跑"到"跑飞"的进化路径

兔哥的技术 994

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

LeetCode力扣-hot100系列(2):高频算法题实战解析与优化技巧

本文深入解析LeetCode力扣hot100系列中的高频算法题,聚焦哈希表、双指针与滑动窗口三大核心技巧。通过剖析“两数之和”、“盛最多水的容器”及“无重复字符的最长子串”等经典例题,详细阐述了如何运用这些技巧进行实战优化,将时间复杂度从O(n²)降至O(n),并分享了代码打磨与边界处理的经验,助力读者从“会做”迈向“精通”。

pz890123的博客 689

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

双指针算法核心:利用单调性实现O(n)高效遍历

在算法优化中,双指针是一种通过两个索引变量协同遍历数据结构(如数组、链表)来提升效率的常用技术。其核心原理在于识别并利用数据或问题本身的单调性——例如有序数组的元素大小关系、链表中快慢指针的相对速度差,或是滑动窗口内统计量的变化趋势。这种单调性确保了指针的每次移动都能确定性地排除部分无效搜索空间,从而将时间复杂度从暴力解法的O(n²)降低至O(n)。从技术价值看,双指针不仅大幅减少了不必要的重复计算,还因其常数级的空间复杂度而成为解决一系列经典问题的首选方案,例如在有序数组中寻找两数之和、判断链表是否有环、

weixin_33802505的博客 335

刷题一个月,我从算法小白变成能独立做中等题的人了

本文分享了一个新手程序员从零开始学习算法的心得。作者坦言最初面对算法题时无从下手,但通过分类刷题(双指针、哈希表、链表、动态规划等)、建立模型感知力、独立思考和总结,一个月后已能解决大部分简单和中等难度题目。关键经验包括:按题型归纳而非盲目刷量、用伪代码梳理思路、分析错误原因,以及培养"识别套路"的能力。作者强调坚持比天赋更重要,鼓励初学者通过持续积累突破瓶颈,并从中获得解决问题的成就感。文章最后建议学习者保持耐心,享受算法学习的成长过程。

zeroFOR112的博客 639

JavaScript开发者的福音:用VibeThinker辅助调试复杂逻辑

VibeThinker-1.5B-APP是一款专为算法与编程优化的轻量级本地AI模型,特别适合JavaScript开发者高效调试复杂逻辑。它在低训练成本下实现高精度代码生成,支持离线部署,能精准辅助如三数之和等去重难题,提供清晰推理路径与注释,显著提升开发效率。

weixin_35826166的博客 763

用TSM训练自己的视频动作识别模型:从UCF101到自定义数据集的完整迁移指南

本文详细介绍了如何将TSM(Temporal Shift Module)视频动作识别模型从UCF101数据集迁移到自定义数据集,涵盖数据结构转换、帧提取、标签管理、训练配置优化及部署实践。特别针对医疗、安防等真实场景中的挑战,提供了实用的解决方案和代码示例,帮助开发者实现高效迁移和部署。

weixin_30847865的博客 262

算法竞赛入门:从复杂度分析到动态规划的核心思想与实践

在计算机科学和编程实践中,算法是解决问题的核心步骤与逻辑描述。其核心价值在于通过优化时间与空间效率,将计算资源转化为解决大规模、高约束实际问题的能力。理解算法的时间复杂度与空间复杂度,就如同为程序进行“体检”,是评估与选择算法的基石。从基础的排序与二分查找,到高效处理连续区间问题的双指针与滑动窗口技巧,再到通过局部最优决策寻求全局解的贪心算法,这些基础思想构成了解决复杂问题的工具箱。动态规划则通过定义状态与状态转移方程,系统性地分解重叠子问题,是实现高效“降维打击”的关键。本文聚焦于算法竞赛的入门核心,结合

weixin_34401479的博客 295

2026最新华为OD机试新系统 机考真题题库 + 真题考点分类 + 备考策略

华为OD机试新系统最新机考重点考点详解以及详细备考策略详解。收录华为OD机试真题中所有题目全部提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及提供在线OJ模拟做题。

qq_45776114的博客 2046

【算法】大厂机考总结和HOT100

【最新最全】华为OD历年机试题集合+OJ刷题网址+刷题经验_华为的外包都要提前刷题 数据库刷题的地址是哪个-优快云博客。

qq_58358642的博客 378

2026最新华为OD机试新系统卷 全覆盖真题题库 + 真题考点分类 + 完整备考策略详解

华为OD机试新系统最新机考全覆盖题库,提供华为OD真题重点题型分类以及详细备考策略详解。华为OD近期真题所有题目全部提供C语言、Java、C++、Python、Go、JavaScript多语言源码实现,并提供完整思路讲解,以及提供在线OJ模拟做题。助力高效提升准备华为OD新系统机试效率。

qq_45776114的博客 903

个人博客目录

个人博客传送门

nanashi_F的博客 531

大学生刷题利器:VibeThinker辅助ACM/ICPC备赛全攻略

VibeThinker-1.5B-APP是一款轻量级开源AI模型,专为算法与数学推理设计,可在本地运行,助力ACM/ICPC备赛。它擅长解析动态规划、组合数学等难题,提供清晰思路与可运行代码,显著提升解题效率,让每位学生都能拥有专属AI教练。

weixin_30415591的博客 868
上一篇: 一条SQL执行过程:从查询到结果的奇幻之旅
下一篇: 一文讲透mysql的索引树:从图书馆的故事开始
路飞说AI
博客等级 码龄10年 214粉丝 24原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值