[双指针] 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;
    }
};
相关推荐
汀、人工智能2 小时前
[特殊字符] 第24课:反转链表
数据结构·算法·链表·数据库架构··反转链表
田梓燊2 小时前
leetcode 41
数据结构·算法·leetcode
_深海凉_2 小时前
LeetCode热题100-三数之和
算法·leetcode·职场和发展
y = xⁿ3 小时前
【LeetCode】双指针合集
算法·leetcode
2601_949539453 小时前
家用新能源 SUV 核心技术科普:后排娱乐、空间工程与混动可靠性解析
大数据·网络·人工智能·算法·机器学习
生信研究猿3 小时前
一个整数转换为二进制
leetcode
凌波粒3 小时前
LeetCode--18.四数之和(双指针法)
数据结构·算法·leetcode
笨笨饿3 小时前
33_顺序表(待完善)
linux·服务器·c语言·嵌入式硬件·算法·学习方法
汀、人工智能3 小时前
[特殊字符] 第26课:环形链表
数据结构·算法·链表·数据库架构··环形链表