1.问题描述
LeetCode:
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)
2.问题分析
使用一个hashmap缓存两个数之和,两边夹逼。
3.代码
//时间复杂度O(n),空间复杂度O(1)
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());
auto last = num.end();
for(auto a = num.begin();a < prev(last,3);++a)
{
for(auto b = next(a);b < prev(lasr,2);++b)
{
auto c = next(b);
auto d = prev(last);
while(c < d)
{
if(*a + *b + *c + *d < target)
++c;
else if(*a + *b + *c + *d < target)
--d;
else
{
result.push_back({*a,*b,*c,*d});
++c;
--d;
}
}
}
}
sort(result.begin(),result.end());
result.erase(unique(result.begin(),result.end()),result.end());
return result;
}
};
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[a] -num[b];
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;
}
};
4.总结
两个方法,一个是先固定两个数,再使用夹逼;二是使用一个hashmap缓存两个数的和,再使用夹逼。