LeetCode OJ:4Sum

4Sum

 

Given an array S of n integers, are there elements abc, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.

Note:

  • Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d)
  • The solution set must not contain duplicate quadruplets.

    For example, given array S = {1 0 -1 0 -2 2}, and target = 0.

    A solution set is:
    (-1,  0, 0, 1)
    (-2, -1, 1, 2)
    (-2,  0, 0, 2)
算法思想:

递归果然超时,改成迭代,时间复杂度从O(n^4)降到O(n^3)


class Solution {
public:
    vector<vector<int> > fourSum(vector<int> &num, int target) {
        
        vector<vector<int>> ans;
        vector<int> tmp;
        int n=num.size();
        
        sort(num.begin(),num.end());
        
        for(int i=0;i<n;)
        {
            for(int j=i+1;j<n;)
            {
                for(int p1=j+1,p2=n-1;p1<p2;)
                {
                    int sum=num[i]+num[j]+num[p1]+num[p2];
                    if ( sum==target)
                    {
                        tmp.clear();
                        tmp.push_back(num[i]);
                        tmp.push_back(num[j]);
                        tmp.push_back(num[p1]);
                        tmp.push_back(num[p2]);
                        ans.push_back(tmp);
                        int t=num[p1];
                        while(p1<p2&&num[p1]==t)
                            p1++;
                    }
                    else if (sum<target)
                        p1++;
                    else
                        p2--;
                }
                int t=num[j];
                while(j<n&&num[j]==t)
                    j++;
            }
            int t=num[i];
            while(i<n&&num[i]==t)
                i++;
        }
        return ans;
    }	
};

ansswer2:

用hashmap缓存,时间复杂度,平均O(n^2),最坏O(n^4),空间复杂度O(n^2)

class Solution {
public:
    vector<vector<int> > fourSum(vector<int> &num, int target) {
        vector<vector<int>> result;
        if(num.size()<4)return result;
        sort(num.begin(),num.end());
        
        unordered_map<int,vector<pair<int,int>>> cache;
        for(size_t a=0;a<num.size();++a){
            for(size_t b=a+1;b<num.size();++b){
                cache[num[a]+num[b]].push_back(pair<int,int>(a,b));
            }
        }
        
        for(size_t c=0;c<num.size();++c){
            for(size_t d=c+1;d<num.size();++d){
                const int key=target-num[c]-num[d];
                if(cache.find(key)==cache.end())continue;
                
                const auto& vec=cache[key];
                for(size_t k=0;k<vec.size();++k){
                    if(c<=vec[k].second)continue;
                    
                    result.push_back({num[vec[k].first],
                        num[vec[k].second],num[c],num[d]});
                }
            }
        }
        sort(result.begin(),result.end());
        result.erase(unique(result.begin(),result.end()),result.end());
        return result;
    }
};

answer3:

用multimap缓存,时间复杂度O(n^2),空间复杂度O(n^2)

class Solution {
public:
    vector<vector<int> > fourSum(vector<int> &num, int target) {
        vector<vector<int>> result;
        if(num.size()<4)return result;
        sort(num.begin(),num.end());
        
        unordered_multimap<int,pair<int,int>> cache;
        for(int i=0;i<num.size();++i)
            for(int j=i+1;j<num.size();++j)
                cache.insert(make_pair(num[i]+num[j],make_pair(i,j)));
                
        for(auto i=cache.begin();i!=cache.end();++i){
            int x=target-i->first;
            auto range=cache.equal_range(x);
            for(auto j=range.first;j!=range.second;++j){
                auto a=i->second.first;
                auto b=i->second.second;
                auto c=j->second.first;
                auto d=j->second.second;
                if(a!=c&&a!=d&&b!=c&&b!=d){
                    vector<int> vec={num[a],num[b],num[c],num[d]};
                    sort(vec.begin(),vec.end());
                    result.push_back(vec);
                }
            }
        }
        sort(result.begin(),result.end());
        result.erase(unique(result.begin(),result.end()),result.end());
        return result;
    }
};



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值