# Leetcode 18. 四数之和

给定数组 nums = [1, 0, -1, 0, -2, 2]，和 target = 0。

[
[-1,  0, 0, 1],
[-2, -1, 1, 2],
[-2,  0, 0, 2]
]

class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
qsort(nums.begin(),nums.end());
return work(nums,0,nums.size(),target,4);
}

vector<vector<int>> work(vector<int>& nums, int start, int stop, int dst, int count) {
vector<vector<int>> result;
if(count == 0 || start>=stop || nums.size()<count) return result;

if(count == 2){
int i=start,j=stop-1;
map<int,int> used;
while(i<j){
int sum=nums[i]+nums[j];
if(used.count(nums[i])!=0){
++i;
continue;
}
if(sum==dst){
result.push_back(vector<int>({nums[i],nums[j]}));
used[nums[i]]=1;
++i;
--j;
}else if(sum>dst){
--j;
}else{
++i;
}
}
return result;
}

map<int,int> used;
for(int i=start;i<stop;++i){
if(used.count(nums[i])!=0){
continue;
}
used[nums[i]]=1;
int newDst=dst-nums[i];
auto vv=work(nums,i+1,stop,newDst,count-1);
if(!vv.empty() ){
for(auto v:vv){
v.push_back(nums[i]);
result.push_back(v);
}
}
}

return result;
}

void qsort(vector<int>::iterator ia, vector<int>::iterator ib){
if(ia+1>=ib) return;

auto start=ia,sentinel=ib-1;
while(start<sentinel){
while(start!=sentinel && *start<=*sentinel) ++start;
swap(*start,*sentinel);

while(start!=sentinel && *start<=*sentinel) --sentinel;
swap(*start,*sentinel);
}

qsort(ia,sentinel);
qsort(sentinel,ib);
}
};