7.LeetCode算法习题讲解--双指针--四数之和

一.题目

习题链接:18. 四数之和 - 力扣(LeetCode)

二.题目分析

给定数组 nums 和目标值 target,寻找所有不重复 的四元组 [nums[a], nums[b], nums[c], nums[d]],满足:

  1. 下标约束:0 ≤ a,b,c,d < n,四个下标互不相等
  2. 数值条件:nums[a]+nums[b]+nums[c]+nums[d] = target
  3. 结果要求:不能包含重复四元组,返回顺序随意

⚠️ 重点区分:下标不同,但元素组合一样 → 视为重复,需要去重。 例:[2,2,2,2] 只能输出一组答案。

这里的题目分析与前面三数之和的讲解一样

三.算法原理讲解

解法一:暴力枚举 + 去重

这里我就不过多介绍了,可以看上一节的三数之和

解法二:双指针 + 去重

思路与三数之和的思路完全相同,三数之和是固定一个数,利用双指针进行查找,这里也是类似,固定两个数,利用双指针进行查找

这里需要注意的是要进行三次去重

四.编写代码

这里有一个注意的点,红色框里面会出现数据溢出的风险,所以这里需要转化为long long

cpp 复制代码
class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int>> ret;
        sort(nums.begin(), nums.end());
        int n = nums.size();
        for(int i = 0; i < n - 3;) // 固定数a
        {
            int a = i;
            for(int j = i + 1; j < n - 2;) // 固定数b
            {
                int b = j, left = j + 1, right = n - 1;
                while(left < right)
                {
                    // 注意数据溢出
                    long long num = (long long)nums[a] + nums[b] + nums[left] + nums[right];
                    if(num > target)
                    {
                        right--;
                    }
                    else if(num < target)
                    {
                        left++;
                    }
                    else
                    {
                        ret.push_back({nums[a], nums[b], 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++;
                while(j < n - 2 && nums[j] == nums[j - 1]) j++;
            }
            // 去重三
            i++;
            while(i < n - 3 && nums[i] == nums[i - 1]) i++;
        }
        return ret;
    }
};
相关推荐
l1t10 分钟前
DeepSeek总结的OpenZL压缩变换器
c++·算法
想吃火锅100510 分钟前
【leetcode】238.除了自身以外数组的乘积js
javascript·算法·leetcode
坤坤子吖32 分钟前
算法学习——高精度加减乘除
c++·笔记·学习·算法
CQU_JIAKE40 分钟前
10.1[A]2267,磐久UMX【上下文128K,KVCache部分]
算法
朝朝辞暮i1 小时前
C++ 第 14 课:引用 &
开发语言·c++·算法
Joe_Wang51 小时前
【从0到1学习JVM · 21】既不浪费空间又没有碎片,标记整理算法到底慢在哪
jvm·学习·算法·垃圾回收·标记整理算法
让学习成为一种生活方式1 小时前
PlantCellChat--单细胞与空间转录组数据预测植物细胞间通讯的R包--The Plant Journal
算法
C++ 老炮儿的技术栈1 小时前
有符号变量与无符号变量的区别
服务器·开发语言·前端·数据结构·c++·算法·c
梦帮科技2 小时前
多任务权重流形融合:SLERP 球形线性插值、DARE 稀疏剪枝与多专家模型融合落地
人工智能·深度学习·算法·机器学习·tensorflow·聚类·剪枝
Tisfy2 小时前
LeetCode 0020.有效的括号:栈匹配
算法·leetcode·字符串·题解·括号匹配