18. 四数相加
给定一个含有 n 个整数的数组 S,数列 S 中是否存在元素 a,b,c 和 d 使 a + b + c + d = target ?
请在数组中找出所有满足各元素相加等于特定值 的 不重复 组合。
注意:解决方案集不能包含重复的四元组合。
例如,给定数组 S = [1, 0, -1, 0, -2, 2],并且给定 target = 0。
示例答案为:
[
[-1, 0, 0, 1],
[-2, -1, 1, 2],
[-2, 0, 0, 2]
]
ps: 做完了两数之和 和 三数之和 的题目再来做这道题是非常简单的。
先将四数之和转换为三数之和的问题即可。同样要注意去重的问题,我们先找出第一个数n1,剩下的三个数在(n1的下标+1, S数组的长度-1)的范围内查找即可。这与三数之和转换为两数之和的查找范围道理是一样的(详见三数之和问题)
static const auto __ = []()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
return nullptr;
}();
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int> >ans;
if(nums.size() < 4)return ans;
sort(nums.begin(), nums.end());
int t_size = nums.size() - 3;
for(int i = 0; i < t_size; i++)
{
if(i && nums[i] == nums[i-1])continue;
int target2 = target - nums[i];
int top3 = i + 1;
int tail3 = t_size + 2;
for(int j = top3; j < nums.size(); j++)
{
if(j != top3 && nums[j] == nums[j - 1])continue;
int target3 = target2 - nums[j];
int top2 = j + 1;
int tail2 = t_size + 2;
while(top2 < tail2)
{
if(nums[top2] + nums[tail2] == target3)
{
ans.push_back({nums[i],nums[j],nums[top2],nums[tail2]});
while((top2 + 1) < tail2 && nums[top2] == nums[top2 + 1])top2++;
while((tail2 - 1 > 0) && nums[tail2] == nums[tail2 - 1])tail2--;
top2++;
tail2--;
}
else if(nums[top2] + nums[tail2] > target3)tail2--;
else top2++;
}
}
}
return ans;
}
};