# leetcode 18 -- 4Sum

## 4Sum

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)

### 代码：

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <iostream>
#include <map>
#include <vector>
#include <set>
#include <algorithm>

using namespace std;

vector<vector<int>> fourSum(vector<int>& nums, int target)
{
vector<vector<int>>ret;
//两个特殊情况
if(nums.size() < 4){
return ret;
}
if(nums.size() == 4){
if(accumulate(nums.begin(), nums.end(), 0) == 0){
ret.push_back(nums);
}
return ret;
}
//里面的set是为了满足排序条件，外面的set是为了满足不重复条件
set<set<int>>sst;
multimap<int, pair<int, int>>two_sum;
//求两两和值
for(int i = 0; i < nums.size(); ++i){
for(int j = i+1; j != nums.size(); ++j){
two_sum.insert({nums[i]+nums[j], {i,j}});
}
}
//定义首尾指针
auto iter1 = two_sum.begin();
//注意iter2不能为two_sum.end()-1,因为two_sum是基于map的没有迭代器减法和加法
auto iter2 = --two_sum.end();
while(iter1 != iter2){
set<int>st;
int add = iter1->first + iter2->first;
//满足条件。添加到set中
st.insert(iter1->second.first);
st.insert(iter1->second.second);
st.insert(iter2->second.first);
st.insert(iter2->second.second);
//如果为4个数字说明无重复且和为0，添加到外层set中
if(st.size() == 4){
sst.insert(st);
}
++iter1;
--iter2;
++iter1;
--iter2;
}
}
//将set中的元素添加到vector中返回即可
for(const set<int>&s : sst){
vector<int>tmp;
for(auto i = s.begin(); i != s.end(); ++i){
tmp.push_back(nums[*i]);
}
sort(tmp.begin(), tmp.end());
ret.push_back(tmp);
}
return ret;
}

int main(int argc, char *argv[])
{
vector<int> nums = {1, 0, -1, 0, -2, 2};
//vector<int> nums = {1, 0, -1, 0, -2, 2, -3, 3, -4, 4};
vector<vector<int>>vvect;
vvect = fourSum(nums, 0);

for(const vector<int>&ivec : vvect){
for(int i : ivec){
cout << i << " ";
}
cout << endl;
}

return EXIT_SUCCESS;
}

测试结果：