【问题】给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。
注意:答案中不可以包含重复的四元组。
示例: 给定数组 nums = [, , -, , -, ],和 target = 。 满足要求的四元组集合为:
[
[-, , , ],
[-, -, , ],
[-, , , ]
]
【思路】
四数之和的大体思路是:首先固定两个数,然后将思路之和的问题变成两数之和,使用双指针的方法去寻找,由于对于两数之和,使用双指针的前提数组是一个排序数组,因此我们先对该数组进行排序,然后根据上述的思路再去遍历。
注意在遍历时候的几种剪枝方法:
如果nums[i]>target && target>0,说明后面的nums[i]肯定不存在我们想要的值,因为后面的值都大于target.
固定的两个元素不能是相同元素,如果是相同的元素,那么经过两数求和算法后势必会存在重复的四元组,因此我们需要判断j > i+1 && nums[j][j-1], 如果为真,两数之和算法不会运行!
两数求和怎么去重的就不解释了,遇到重复的,让指针跳过就好了!
如果不想这么麻烦,可以使用DFS方法中的set去重
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
if(nums.size()<) return {};
sort(nums.begin(),nums.end());
vector<vector<int>> res;
for(int i=;i<nums.size()-;i++)
{
if(nums[i]>target&&target>) break;
if(i> && nums[i]==nums[i-])
continue; // 去重
for(int j=i+;j<nums.size()-;j++)
{
if(j>i+ && nums[j]==nums[j-])
continue; // 去重
int l=j+;
int r=nums.size()-;
while(l<r)
{
if(nums[i]+nums[j]+nums[l]+nums[r]<target)
while(l<r && nums[l]==nums[++l]); // 去重
else if(nums[i]+nums[j]+nums[l]+nums[r]>target)
while(l<r && nums[r]==nums[--r]);
else
{
vector<int> temp{nums[i],nums[j],nums[l],nums[r]};
res.push_back(temp);
while(l<r && nums[l]==nums[++l]);
while(l<r && nums[r]==nums[--r]);
}
}
}
}
return res;
}
};