4Sum - LeetCode

本文深入探讨了LeetCode上四数之和问题的两种解法。第一种解法通过在3Sum基础上增加一层循环实现,时间复杂度为O(n^3);第二种解法则利用哈希表进行优化,尽管时间复杂度降低至O(n^2),但因去重过程复杂,实际效率可能不如前者。文章还详细介绍了代码实现及优化技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接

Merge Two Sorted Lists - LeetCode

注意点

  • 和3Sum那道题一样

解法

解法一:在3Sum的基础上再加一层循环即可。时间复杂度为O(n^3)

class Solution {
public:
    using num_t = vector<int>;
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        int n = nums.size(),newTarget,i = n-1,j,l,r;
        vector<num_t> ans;
        if(n < 4) return ans;
        sort(nums.begin(),nums.end());
        while(i >= 3)
        {
            newTarget = target - nums[i];
            j = i-1;
            while(j >= 2)
            {
                l = 0;
                r = j-1;
                while(l < r)
                {
                    int sum = nums[l]+nums[r]+nums[j];
                    if(sum < newTarget) l++;
                    else if(sum > newTarget) r--;
                    else
                    {
                        ans.push_back({nums[i],nums[j],nums[l],nums[r]});
                        l++;
                        r--;
                        while (l<r && nums[l-1]==nums[l]) l++;     
                        while (l<r && nums[r+1]==nums[r]) r--;
                    }
                }
                j--;
                while(j >= 2 && nums[j+1]==nums[j]) j--;
            }
            i--;
            while(i >= 3 && nums[i+1]==nums[i]) i--;
        }
        return ans;
    }
};

874b0eb1gy1fzpqn9uuhmj216k0jtgmk.jpg

解法二:看了评论得到的思路。先二重循环,将所有可能出现的两数之和的值map保存。然后再二重循环,计算两数之和,比较加上map中存的值之后是否等于target。时间复杂度为O(n^2)

class Solution {
public:
    using num_t = vector<int>;
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<num_t> ret;
        int n = nums.size(),i,j;
        if(n < 4) return ret;
        unordered_map<int,vector<pair<int,int>>> myMap;
        for(i = 0;i < n;i++)
        {
            for(j = i+1;j < n;j++)
            {
                myMap[target - nums[i] - nums[j]].push_back({i,j});
            }
        }
        for(i = 0;i < n;i++)
        {
            for(j = i+1;j < n;j++)
            {
                int temp = nums[i] + nums[j];
                if(myMap.count(temp))
                {
                    for(auto p:myMap[temp])
                    {
                        if(p.first != i && p.first != j && p.second != i && p.second != j)
                        {
                        ret.push_back({nums[p.first],nums[p.second],nums[i],nums[j]});
                        }
                    }
                }
            }
        }
        n = ret.size();
        for(i = 0;i < n;i++)
        {
            sort(ret[i].begin(),ret[i].end());
        }
        sort(ret.begin(),ret.end());
        ret.erase(unique(ret.begin(),ret.end()),ret.end());
        
        return ret;
    }
};

874b0eb1gy1fzpsgd2qa8j217y0k7ab2.jpg

注:虽然这道题时间复杂度为O(n^2)但是去重所花的时间过多,导致最终所花时间甚至高于O(n^3)
再注:去重所花时间是固定的,取决于输入的数组长度。所以在求nSum的问题的时候,随着n的增大,解法二更有优势。

小结

  • unique函数
  • map中key对应的value是唯一的,如果想一个key对应多个value可以像解法二一样,构造一个map<int,vector<int>>

转载于:https://www.cnblogs.com/multhree/p/10342168.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值