题目链接:https://leetcode.com/problems/4sum/#/description
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] ]
方法一(超时)
class Solution{
public:
vector<vector<int>> fourSum(vector<int>& nums,int target)
{
sort(nums.begin(),nums.end());
vector<vector<int>> res;
vector<int> tmp;
dfs(nums,target,res,tmp,0);
return res;
}
void dfs(vector<int>& nums,int target,vector<vector<int>>& res,vector<int> tmp,int start)
{
if(tmp.size()==4)
{
if(accumulate(tmp.begin(),tmp.end(),0)==target && find(res.begin(),res.end(),tmp)==res.end())
res.push_back(tmp);
return;
}
for(int i=start;i<nums.size();i++)
{
tmp.push_back(nums[i]);
dfs(nums,target,res,tmp,i+1);
tmp.pop_back();
}
}
};
方法二:
思路:
- 对数组排序
- 确定四元数中的前两个(a,b)
- 遍历剩余数组确定两外两个(c,d),确定cd时思路跟3Sum确定后两个数据一样,二分查找左右逼近。
- 在去重时采用set集合
class Solution {
public:
vector<vector<int> > fourSum(vector<int> &num, int target) {
int i,j,start,end;
int Len = num.size();
vector<int> triplet;
vector<vector<int>> triplets;
set<vector<int>> sets;
//排序
sort(num.begin(),num.end());
for(i = 0;i < Len-3;i++){
for(j = i + 1;j < Len - 2;j++){
//二分查找
start = j + 1;
end = Len - 1;
while(start < end){
int curSum = num[i] + num[j] + num[start] + num[end];
//相等 -> 目标
if(target == curSum){
triplet.clear();
triplet.push_back(num[i]);
triplet.push_back(num[j]);
triplet.push_back(num[start]);
triplet.push_back(num[end]);
sets.insert(triplet);
start ++;
end --;
}
//大于 -> 当前值小需要增大
else if(target > curSum){
start ++;
}
//小于 -> 当前值大需要减小
else{
end --;
}
}//while
}
}//for
//利用set去重
set<vector<int>>::iterator it = sets.begin();
for(; it != sets.end(); it++)
triplets.push_back(*it);
return triplets;
}
};
class Solution {
public:
vector<vector<int> > fourSum(vector<int> &num, int target) {
int i,j,start,end;
int Len = num.size();
vector<int> triplet;
vector<vector<int>> triplets;
set<vector<int>> sets;
//排序
sort(num.begin(),num.end());
for(i = 0;i < Len-3;i++){
if(i>0 && num[i]==num[i-1])
continue;
for(j = i + 1;j < Len - 2;j++){
if(j>1 && num[j]==num[j-1])
continue;
//二分查找
start = j + 1;
end = Len - 1;
while(start < end){
int curSum = num[i] + num[j] + num[start] + num[end];
//相等 -> 目标
if(target == curSum){
triplet.clear();
triplet.push_back(num[i]);
triplet.push_back(num[j]);
triplet.push_back(num[start]);
triplet.push_back(num[end]);
triplets.push_back(triplet);
start ++;
end --;
while(start<end && num[start]==num[start-1])start++;
while(start<end && num[end]==num[end+1])end--;
}
//大于 -> 当前值小需要增大
else if(target > curSum){
start ++;
}
//小于 -> 当前值大需要减小
else{
end --;
}
}//while
}
}//for
//利用set去重
// set<vector<int>>::iterator it = sets.begin();
// for(; it != sets.end(); it++)
// triplets.push_back(*it);
return triplets;
}
};