【C++算法】9.双指针_四数之和

文章目录


题目链接:

18.四数之和


题目描述:


解法

解法一:排序+暴力枚举+利用set去重
解法二:排序+双指针

  1. 从左往右依次固定一个数a
  2. a后面的区间里,利用"三数之和"找到三个数,使这三个数的和等于target-a即可
  3. 在上面一步的"三数之和"里面,我们先固定一个b,在b后面的区间里面,利用"双指针"找到两个数,使这两个数的和等于target-a-b即可。

处理细节:

  1. 不重

    • 双指针要跳过相同元素
    • b要跳过相同元素
    • a要跳过相同元素
  2. 不漏

    双指针遇到合适的数继续往后走


C++ 算法代码:

cpp 复制代码
class Solution 
{
    public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) 
    {
        vector<vector<int>> ret;
        // 1. 排序
        sort(nums.begin(), nums.end());
        // 2. 利用双指针解决问题
        int n = nums.size();
        for(int i = 0; i < n; ) // 固定数 a
        {
            // 利用 三数之和
            for(int j = i + 1; j < n; ) // 固定数 b
            {
                // 双指针
                int left = j + 1, right = n - 1;
                long long aim = (long long)target - nums[i] - nums[j];//aim = target - a - b
                while(left < right)
                {
                    int sum = nums[left] + nums[right];
                    if(sum < aim) {
                        left++;
                    }
                    else if(sum > aim) {
                        right--;
                    }
                    else
                    {
                        ret.push_back({nums[i], nums[j], nums[left++], 
                                       nums[right--]});//ret数组存放最终结果
                        // 去重一
                        while(left < right && nums[left] == nums[left - 1]) { 
                            left++;
                        }
                        while(left < right && nums[right] == nums[right + 1]) {
                            right--;
                        }
                    }
                }
                // 去重二
                j++;
                while(j < n && nums[j] == nums[j - 1]) {
                    j++;
                }
            }
            // 去重三
            i++;
            while(i < n && nums[i] == nums[i - 1]) {
                i++;
            }
        }
        return ret;
    }
};

图解

nums=[1,0,-1,0,-2,2]

target=0

  1. n=6,i=0,j=1,left=2,right=5,aim=-1
  1. left<right,sum=-1+2=1>aim,right--
  1. left<right,sum=-1-2=-3<aim,left++
  1. left<right,sum=0-2=-2<aim,left++

  2. 不满足循环条件,跳出while循环,进入去重2j++

  1. n=6,i=0,j=2,left=3,right=5,aim=0

  2. 后面的步骤类似,就不多赘述了。

相关推荐
码哥DFS8 分钟前
构造函数、实例对象、对象原型 ----三者关系
开发语言·javascript·原型模式
不爱学英文的码字机器10 分钟前
推荐算法梳理,六种主流模型与九步训练流程
算法·机器学习·推荐算法
quantdash_cc37 分钟前
告别自建 Requests/BS4 网页爬虫:基于 QuantDash 搭建零维保的高性能量化行情流水线
开发语言·爬虫·python·pandas·量化·quantdash
ydd10010044 分钟前
寻找两个正序数组的中位数 Java 题解,二分分割详解
java·开发语言
白狐_7981 小时前
408数据结构第5章:树与二叉树②——遍历、线索树、森林与哈夫曼
数据结构·算法·深度优先
zh路西法1 小时前
【3D SLAM源码解读系列】(二)Small_gicp——5 个积木搭出最优点云配准
c++·pcl·icp·fastgicp·smallgicp·gicp
半亩码田1 小时前
C#转Python第3.1篇:Python 的 class 没有访问修饰符?面向对象的另一条路
开发语言·python·c#
Wzx1980122 小时前
python沙箱和docker沙箱你选对了吗?
开发语言·python·docker
牧羊人.3332 小时前
Python 办公自动化从入门到入土|09 数据容器之字典
开发语言·python
小僧景贤2 小时前
嵌入式C语言 第二篇:基础语法|嵌入式C与标准C的核心差异
c语言·开发语言·嵌入式c语言