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

算法实战:双指针解决三数之和与四数之和

利用排序加双指针技巧解决三数之和与四数之和问题。核心在于固定部分元素后,将剩余问题转化为两数之和,通过移动左右指针寻找目标值。重点处理重复元素去重逻辑,避免结果冗余。代码实现中需注意整数溢出风险,特别是在四数之和中使用 long long 类型。该方案时间复杂度为 O(n^2),是面试中的高频考点。

ByteFlow发布于 2026/3/29更新于 2026/10/24114 浏览
算法实战:双指针解决三数之和与四数之和

前言

在算法面试中,双指针是处理数组相关问题的利器。今天聚焦两个经典题目:三数之和与四数之和。它们都可以通过'排序 + 双指针'的策略将暴力解法的 O(n^3) 优化到 O(n^2)。

三数之和

题目描述

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。 LeetCode 链接

解题思路

这题的核心在于如何高效地找到三个数且保证不重复。

  1. 排序:先对数组进行排序,这样相同的数字会挨在一起,方便去重。
  2. 固定 + 双指针:遍历数组,固定第一个数 nums[i]。然后在 i 之后的区间里,用双指针 left 和 right 寻找另外两个数,使它们的和等于 -nums[i]。
  3. 去重细节:这是最容易出错的地方。
    • 如果 nums[i] 和前一个数相同,说明这个位置已经处理过了,直接跳过。
    • 当找到一组解后,left 右移、right 左移时,也要跳过所有重复的值,防止结果集中出现重复三元组。
    • 还有一个剪枝优化:如果 nums[i] > 0,因为数组已排序,后面的数肯定都大于 0,三数之和不可能为 0,可以直接结束循环。

C++ 代码实现

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> ret;
        int n = nums.size();
        // 排序是双指针的前提
        sort(nums.begin(), nums.end());

        for (int i = 0; i < n; ) {
            // 剪枝:如果当前数大于 0,后续不可能有和为 0 的组合
            if (nums[i] > 0) break;

            int left = i + 1, right = n - 1;
            int target = -nums[i];

             (left < right) {
                 sum = nums[left] + nums[right];
                 (sum < target) {
                    left++;
                }   (sum > target) {
                    right--;
                }  {
                    ret.({nums[i], nums[left], nums[right]});
                    left++;
                    right--;
                    
                     (left < right && nums[left] == nums[left - ]) left++;
                     (left < right && nums[right] == nums[right + ]) right--;
                }
            }
            
            i++;
             (i < n && nums[i] == nums[i - ]) i++;
        }
         ret;
    }
};
while
int
if
else
if
else
push_back
// 去重:跳过重复的 left 和 right
while
1
while
1
// 去重:跳过重复的 i
while
1
return

四数之和

题目描述

给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] 。 LeetCode 链接

解题思路

四数之和可以看作是三数之和的扩展。

  1. 双重固定:外层循环固定第一个数 nums[i],内层循环固定第二个数 nums[j]。
  2. 双指针查找:在 j 之后使用双指针寻找剩余两个数,使总和等于 target。
  3. 数据溢出注意:计算目标和时,target - nums[i] - nums[j] 可能会超出 int 范围,务必使用 long long 存储中间结果。
  4. 去重逻辑:与三数之和类似,每一层循环遇到重复元素都要跳过。

C++ 代码实现

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int>> ret;
        int n = nums.size();
        sort(nums.begin(), nums.end());

        for (int i = 0; i < n; ) {
            for (int j = i + 1; j < n; ) {
                int left = j + 1, right = n - 1;
                // 使用 long long 防止求和溢出
                long long targetSub = (long long)target - nums[i] - nums[j];

                while (left < right) {
                    long long sum = (long long)nums[left] + nums[right];
                    if (sum < targetSub) {
                        left++;
                    } else if (sum > targetSub) {
                        right--;
                    } else {
                        ret.push_back({nums[i], nums[j], nums[left], nums[right]});
                        left++;
                        right--;
                        // 去重
                        while (left < right && nums[left] == nums[left - 1]) left++;
                        while (left < right && nums[right] == nums[right + 1]) right--;
                    }
                }
                // 去重 j
                j++;
                while (j < n && nums[j] == nums[j - 1]) j++;
            }
            // 去重 i
            i++;
            while (i < n && nums[i] == nums[i - 1]) i++;
        }
        return ret;
    }
};

目录

  1. 前言
  2. 三数之和
  3. 题目描述
  4. 解题思路
  5. C++ 代码实现
  6. 四数之和
  7. 题目描述
  8. 解题思路
  9. C++ 代码实现

更多推荐文章

查看全部
  • Llama3 中文大模型快速部署与优化指南
  • C++实现机械臂力控算法全过程详解
  • AI 自动化测试:接口测试全流程自动化的实现方法
  • Stable Diffusion 大模型详解:版本、差异与推荐
  • 阿里开源 PageAgent:纯前端 JS 实现网页自然语言操控
  • OpenVLA 深度解析:基于 Prismatic VLM 的离散化动作预测
  • Git 安装流程与基础使用指南
  • Stable Diffusion 与 Z-Image-Turbo 快速搭建与效果对比方案
  • Whisper ASR Webservice 快速部署与 API 使用指南
  • 近五年体内微/纳米机器人赋能肿瘤精准治疗综述:聚焦胶质母细胞瘤
  • 程序员必知的 10 大代码共享与协作平台
  • 前端国际化最佳实践指南
  • 基于 DeepFace 和 OpenCV 的情绪分析器实现
  • 人工智能 Gemini 2.5 Pro:技术突破与实战应用
  • 基于 OpenClaw 搭建三 Agent 协作写作系统
  • 深入理解 YOLOv11 算法核心模块与结构
  • 2025 腾讯广告算法大赛 Baseline 项目解析
  • Oracle 中 CONNECT BY PRIOR 递归查询用法
  • WebGIS 实现城市停水影响范围可视化实践
  • Python IDE 选型指南:PyCharm、VS Code 与 IDLE 对比

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如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