跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

双指针算法:两数之和与三数之和

通过和为 S 的两数之和与三数之和两个经典问题,深入讲解双指针算法的应用。首先分析暴力解法的时间复杂度缺陷,随后利用数组有序特性,介绍双指针从两端向中间移动的原理。针对两数之和,实现 O(N) 时间复杂度;针对三数之和,结合排序与去重策略,固定一个数并使用双指针查找另外两数,有效解决重复元素问题并优化性能。

laoliangsh发布于 2026/3/26更新于 2026/5/216.3K 浏览
双指针算法:两数之和与三数之和

目录

前言

和为 s 的两数之和

题目解析

算法原理

算法编写

三数之和

题目解析

算法原理

算法编写

前言

本文通过介绍和为 S 的两数之和,以及三数之和,对双指针算法进行深一步的了解。

和为 s 的两数之和

题目解析

文章配图

文章配图

该题目的要求是找到两个数,这两个数相加的和是等于 target 的。题中也有个很重要的条件,按照升序记录于数组中,这个升序是十分关键的。

我们直接探讨暴力解法,即将所有的两数之和举例出来,第一次相等就返回即可。如果运气差点,就需要遍历完整个数组两次,即两个 for 循环,此时的时间复杂度为 O(N^2),这是暴力解法,是比较容易想出来的:

for (int i = 0; i < price.size(); i++) {
    for (int j = 0; j < price.size(); j++) {
        // 判断是否满足条件
    }
}

当然了,如果使用暴力解法,那么我们对题目的升序就没有任何使用了,就很吃亏,所以现在进入算法原理。

算法原理

使用双指针算法,对于题目中的升序,一定要利用好。我们知道:

target = num1 + num2

那么既然是升序的,如果我们让两个指针,一个从开始走,一个从末尾走,也就是最大的和最小的走,判断结果,大于了 target,右指针往左边走,反之亦然,这时候其实已经做完题目了。

对于循环来说,只有一个循环,如果没有找到,返回的是个空就可以。

算法编写

class Solution {
public:
    vector<int> twoSum(vector<int>& price, int target) {
        int right = price.size() - 1, left = 0;
        while(left < right) {
            if(price[left] + price[right] == target) return {price[left], price[right]};
            else if(price[left] + price[right] < target) left++;
            else if(price[left] + price[right] > target) right--;
        }
        return {};
    }
};

结束条件自然是左小于右,因为返回的是 vector,都没有找到的话返回空即可,时间复杂度是 O(N),没有新开空间,所以空间复杂度为 O(1)。

三数之和

题目解析

文章配图

文章配图

文章配图

由题目可得,找三个数,其中这三个数相加等于 0,我们不妨将题目理解为,找一个数,该数 = 另外两数之和,是不是就感觉容易多了?不过是上文和为 s 的变种而已,我们只是需要将 S 变化一下即可。

以上是题目的最基本的要求,那么还有一个要求是,不允许出现重复的,这是和本文第一道题不同的要求,这点代表了我们要去重即可。

那么同样的,我们思考如何暴力解法?

暴力解法无非是将所有的三元组列出来,判断和是否为零,满足条件,我们可以将它丢进 set,用 set 本身的性质进行去重即可。

但是暴力解法的时间复杂度可就高了,三个数都要单独列出,也就是需要三个循环,时间复杂度为 O(N^3),往往是通过不了的。

所以,我们进入到算法原理方面。

算法原理

我们同样的使用双指针算法,因为是双指针不是三指针,所以需要我们固定一个数,用来充当 target,有了第一个题目的经验,我们不妨排序一下,保证数组有序的同时有利于我们控制指针变量,排序之后对于我们去重的操作也会容易很多。

排序之后,固定好 target,然后进入到第二个循环,通过双指针算法,找两个数,使该三个数相加等于 0 即可。

那么指针移动分为两种情况,如果前面两个数相加>target,代表 right 大了,需要 right--,反之亦然,这是移动的情况。满足条件的话,添加进去就可以了。

那么最重要的点来了,我们如何进行去重操作呢?

判断的是 nums[left] == nums[left + 1] 是否相等即可,如果相等了,left 就++,right 同理,但是去重的不只有这两个数,还有一个数也需要去重,就是 nums[i],如果 i 不去重,肯定是很导致很多重复的元素,毕竟都是会从头开始找的。

去重 i 的时候,需要控制 i 的移动,因为去重操作本身就会控制指针移动。

算法编写

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> ans;
        sort(nums.begin(), nums.end());
        for(int i = nums.size() - 1; i > 1 && nums[i] >= 0;) {
            int target = nums[i];
            int left = 0, right = i - 1;
            while(left < right) {
                if(nums[left] + nums[right] > (-target)) right--;
                else if(nums[left] + nums[right] < (-target)) left++;
                else {
                    ans.push_back({nums[left++], nums[right--], nums[i]});
                    while(left < right && nums[left] == nums[left - 1]) left++;
                    while(left < right && nums[right] == nums[right + 1]) right--;
                }
            }
            i--;
            while(i < nums.size() && nums[i] == nums[i + 1]) i--;
        }
        return ans;
    }
};

三个去重,一个排序,三个判断,最后返回即可。

目录

  1. 前言
  2. 和为 s 的两数之和
  3. 题目解析
  4. 算法原理
  5. 算法编写
  6. 三数之和
  7. 题目解析
  8. 算法原理
  9. 算法编写
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Python 爬虫实现豆瓣电影数据采集实战
  • 利用 AI 大模型与 TradingView 构建自动交易策略
  • OpenClaw 网络搜索与抓取工具最佳实践指南
  • 大模型 Agent 核心解析:Prompt、架构与挑战
  • 机器人架构搭建核心准则:先论文论证后工程落地
  • Python 入门实战:从零编写你的第一个网络爬虫
  • Cursor 集成 MCP 服务实战:环境配置与自动化应用
  • 大型语言模型(LLM)微调技术全面总结
  • Python 入门教程:从基础语法到控制流
  • 数据库 SQL 防火墙:内核级防护与注入防御机制
  • AI 时代人才新逻辑:深度专业与跨界能力的复合进化
  • C++ 模板进阶:特化、萃取与可变参数实战
  • 零基础网络安全入门指南:学习路径与核心技能解析
  • FastAPI:Python 高性能 Web 框架深度解析
  • C++ 哈希表封装:模拟实现 unordered_map 与 unordered_set
  • Elasticsearch 全文搜索与数据分析实战指南
  • 企业级招聘数据采集:基于 Bright Data AI Studio 的自动化爬虫方案
  • Web3 入门:从比特币到以太坊智能合约
  • 激光雷达外参标定算法详解
  • 数据结构详解:堆、哈希表与字符串哈希

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online