[双指针] 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;
    }
};
相关推荐
吃好睡好便好1 分钟前
在Matlab中绘制杆状图
开发语言·学习·算法·matlab·信息可视化
带带弟弟学爬虫__2 分钟前
dyAPP数据采集-个人主页、发布、搜索、评论
服务器·python·算法·flutter·java-ee·django
sali-tec7 分钟前
C# 基于OpenCv的视觉工作流-章75-线-线角度
图像处理·人工智能·opencv·算法·计算机视觉
大熊背17 分钟前
Binning模式下和Normal模式下加权平均亮度差异分析以及优化
人工智能·算法·自动曝光
思茂信息17 分钟前
CST案例:可调谐全硅手性超表面在太赫兹频段
网络·人工智能·算法·重构·cst·电磁仿真
呃呃本36 分钟前
算法题(动态规划)
算法·动态规划
pen-ai1 小时前
Kennard-Stone (KS) 算法详解 —— 从实验设计到样本划分的经典方法
人工智能·算法·机器学习
开压路机1 小时前
数据结构:图
数据结构·算法
小白|1 小时前
cann-learning-hub:昇腾CANN社区学习中心完全指南
java·c++·算法
kobesdu1 小时前
当算法跑不通时:3D激光SLAM工程实践中的隐藏陷阱与全链路排查
算法·3d