#include <iostream>
#include <vector>
#include<algorithm>
#include <queue>
using namespace std;
/************************************************************************/
/*
Problem:
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: 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]
]
Author : crazys_popcorn@126.com
DateTime: 2017年8月5日 12:06:17
*/
/************************************************************************/
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target)
{
vector< vector <int > >_result;
int _size = nums.size();
if (nums.size() < 4)
return _result;
sort(nums.begin(), nums.end());
for (int i = 0; i < _size - 3; i++)
{
if (i>0 && nums[i]== nums[i-1])
continue;
if (nums[i]+nums[i+1]+nums[i+2] +nums[i+3]> target)
break;
if (nums[i] + nums[_size - 1] + nums[_size - 2] + nums[_size - 3] < target)
continue;
for (int j = i + 1;j <_size - 2; j++)
{
//为什么要用j > i+1 因为这是 要往后推迟一个。不要让他和i相比 也就是前一位数字
if ( j > i +1 &&nums[j] == nums[j - 1])
continue;
if (nums[i] + nums[j] + nums[j+1] + nums[j+2]> target)
break;
if (nums[i] + nums[_size - 1] + nums[_size - 2] + nums[j] < target)
continue;
int k = j + 1, m = _size - 1;
while (k < m)
{
int sum = nums[i] + nums[j] + nums[k] + nums[m];
if (sum <target)k++;
else if (sum > target) m--;
else
{
_result.push_back(vector<int>{ nums[i], nums[j], nums[k], nums[m] });
do{ k++;} while (nums[k] == nums[k - 1] && k < m);
do{ m--;} while (nums[m] == nums[m + 1] && k < m);
}
}
}
}
return _result;
}
};
void main()
{
Solution s1;
// 0 1 2 3 4 5 6 7
vector<int> _temp = { -5, -5, -3, -1, 0, 2, 4, 5 };
vector<vector<int>> num = s1.fourSum(_temp, -11);
std::cout << "" << endl;
system("pause");
}