[双指针] 8. 四数之和

题目链接

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

一. 题目描述

cpp 复制代码
class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        
    }
};

二. 解题思路

1)本题解题思路和上一篇的三数之和基本一样,只不过多固定一个数,再用双指针。

2)如果使用暴力解法来暴力枚举四个数,时间复杂度将是O(N^4)级别的,双指针算法可以降一维达到O(N^3)。

3)优化算法核心思路

  1. 排序。

  2. 依次固定一个数a。

  3. 在a后面的区间使用 "三数之和" 找到三个数。

  4. 在三数之和的方法中:依次固定一个数b。

  5. 在后面的区间内,使用 "双指针算法" 找到两个数,使这两个数的和为 target - a - b。

  6. 细节问题

① 不漏:找到一组正确的值之后,不要停止,两指针继续向内移动缩小区间继续寻找。

② 不重:不重复这里有三个位置需要注意,第一个双指针位置不能指向重复值;第二个是固定的数b不能固定重复的值;第三个是固定的数a不能固定重复的值。

三. 易错测试用例

nums = { 1000000000,1000000000,1000000000,1000000000 };

target = -294967296;

这条测试用例中的值是10^9,和int的最大值是同一个量级的,在加减运算时会溢出。所以我们要用范围更大的long long

四. 代码实现

cpp 复制代码
class Solution 
{
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) 
    {
        vector<vector<int>> retvv;
        size_t size = nums.size();

        sort(nums.begin(), nums.end());

        // 依次固定第一个数
        for(size_t i = 0; i < size; i++)
        {
            // 第一个固定的数不重复
            if(i && nums[i] == nums[i-1]) continue;

            // 依次固定第二个数
            for(size_t j = i + 1; j < size; j++)
            {
                // 第二个固定的数不重复
                if(j != i+1 && nums[j] == nums[j-1]) continue;

                size_t left = j+1, right = size-1;
                long long newtarget = (long long)target - nums[i] - nums[j];
                // 找双指针指向元素之和等于newtarget
                while(left < right)
                {
                    long long sum = nums[left] + nums[right];
                    if(sum > newtarget) right--;
                    else if(sum < newtarget) left++;
                    else
                    {
                        retvv.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--;
                    }
                }
            }
        }
        return retvv;
    }
};
相关推荐
想吃火锅100518 小时前
【leetcode】54. 螺旋矩阵
算法·leetcode·矩阵
想吃火锅100519 小时前
【leetcode】300. 最长递增子序列
算法·leetcode·职场和发展
数模竞赛Paid answer19 小时前
2026年电工杯数学建模A题绿电直连型电氢氨园区优化运行求解全过程论文及程序
算法·数学建模·电工杯
疯狂打码的少年19 小时前
【数据结构】串的模式匹配:KMP算法(重点)
数据结构·笔记·算法
晚风醉蝶20 小时前
第零篇-算法全景图
算法
疯狂打码的少年20 小时前
【数据结构】树的基本概念与二叉树定义
java·数据结构·笔记·算法
webmote3320 小时前
用 NVIDIA Nemotron 3 Super + .NET 构建有记忆的多轮对话
后端·算法
Keven_1121 小时前
算法札记:区分稀疏图与稠密图在经验上的数学计算差异
算法·稠密图·稀疏图
Sagittarius_A*21 小时前
后量子密码|前置基础 03|数字签名运行逻辑:签名签发、核验原理与实际业务应用
算法·信息安全·密码学·数字签名·后量子密码
DBA小马哥21 小时前
向量数据库入门到进阶:Embedding、ANN算法与RAG落地的关键术语
数据库·算法·embedding