Given an array S of n integers, are there elements a, b, c, 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^2)
用两个for循环以及预处理过的数对
class Solution{
public:
vector<vector<int> > fourSum(vector<int> &num, int target) {
unordered_map<int,int> m;
//O(n) initialize
for(int i=0;i<num.size();i++){
if(m.find(num[i])==m.end()){
m[num[i]]=1;
}
else{
m[num[i]]++;
}
}
//O(n^2) initialize
unordered_map<int, set<vector<int> > > m2;
vector<int> p;
p.resize(2);
for(int i=0;i<num.size();i++){
for(int j=i+1;j<num.size();j++){
int b,s;
if(num[i]>num[j]){
b=num[i];
s=num[j];
}
else{
b=num[j];
s=num[i];
}
p[0]=s;
p[1]=b;
m2[b+s].insert(p);
}
}
vector<int> one;
one.resize(4);
set<vector<int> >::iterator it;
set<vector<int> >res;
vector<vector<int> > ret;
for( int i=0;i<num.size();i++)
{
for(int j=i+1;j<num.size();j++){
int tt=target-num[i]-num[j];
if(m2.find(tt)!=m2.end()){
set<vector<int> >& ss=m2[tt];
for(it=ss.begin();it!=ss.end();it++){
one[0]=num[i];
one[1]=num[j];
one[2]=(*it)[0];
one[3]=(*it)[1];
sort(one.begin(),one.end());
int current=one[0];
int count=1;
for(int i=1;i<4;i++){
if(one[i]==current){
count++;
}
else{
if(count>m[current])
continue;
else current=one[i];
count=1;
}
}
if(count>m[current])continue;
res.insert(one);
}
}
}
}
set<vector<int> >::iterator itt;
for(itt=res.begin();itt!=res.end();itt++){
ret.push_back(*itt);
}
return ret;
}
};