1.递归+回溯
需要考虑数组中可能存在重复的元素,故先对数组进行排序
遍历数组,当前元素与其前的元素值相同时,则跳过
代码如下:
class Solution {
vector<vector<int>> res;
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
int len=nums.size();
vector<int> ans;
sort(nums.begin(),nums.end());
for(int i=0;i<len-3;i++)
{
if(i>0&&nums[i]==nums[i-1])
continue;
ans.push_back(nums[i]);
dfs(nums,ans,i+1,target);
ans.pop_back();
}
return res;
}
void dfs(vector<int> &nums,vector<int> &ans,int start,int target)
{
if(ans.size()==4)
{
if(ans[0]+ans[1]+ans[2]+ans[3]==target)
{
res.push_back(ans);
return;
}
}
for(int i=start;i<nums.size();i++)
{
if(i>start&&nums[i]==nums[i-1])
continue;
ans.push_back(nums[i]);
dfs(nums,ans,i+1,target);
ans.pop_back();
}
}
};
效率太低,结果超时
2.双层遍历+双指针
先排序,双层遍历之后使用双指针
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
sort(nums.begin(),nums.end());
vector<vector<int>> result;
int size=nums.size();
for(int a=0;a<size-3;++a)
{
if(a>0&&nums[a]==nums[a-1])continue;
for(int b=a+1;b<size-2;++b)//以下代码与三数之和一样的
{
if(b>a+1&&nums[b]==nums[b-1])continue;
int i=b+1,j=size-1;
while(i<j)
{
int sum=nums[a]+nums[b]+nums[i]+nums[j];
if(sum<target)
while(i<j&&nums[i]==nums[++i]);
else if(sum>target)
while(i<j&&nums[j]==nums[--j]);
else{
result.push_back(vector<int>{nums[a],nums[b],nums[i],nums[j]});
while(i<j&&nums[i]==nums[++i]);
while(i<j&&nums[j]==nums[--j]);
}
}
}
}
return result;
}
};