题目描述:
给定一个包含 n 个整数的数组 nums
和一个目标值 target
,判断 nums
中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target
相等?找出所有满足条件且不重复的四元组。
注意:
答案中不可以包含重复的四元组。
示例:
给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。 满足要求的四元组集合为: [ [-1, 0, 0, 1], [-2, -1, 1, 2], [-2, 0, 0, 2] ]
解题思路:
先排序,在定四个索引: a, b, c, d; 其中a, b依次从头到尾开始遍历,c定在b+1,d定在nums.size()-1, 然后c, d慢慢靠拢。如果nums[a] + nums[b] + nums[c] + nums[d] > target,在前面基数a,b固定的情况下,则只能移动d--,才能使和变小,才有可能找到相等的索引,反之如果<target,则只能c++
C++代码:
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> result; // 二维数组
int N=nums.size();
if(N<4) return result;
sort(nums.begin(),nums.end()); // 先排序
for(int a=0;a<N-3;a++){ // a = n-4, b = n-3, c = n-2, d = n -1
if(a>0 && nums[a]==nums[a-1])continue; //跳过重复
if(nums[a]+nums[a+1]+nums[a+2]+nums[a+3]>target)break;//太大了
if(nums[a]+nums[N-3]+nums[N-2]+nums[N-1]<target)continue;//太小了,以当前a为基
for(int b=a+1;b<N-2;b++){ // b= n-3, c = n-2, d = n -1
if(b>a+1 && nums[b]==nums[b-1])continue;//跳过重复
if(nums[a]+nums[b]+nums[b+1]+nums[b+2]>target)break;//太大了
if(nums[a]+nums[b]+nums[N-2]+nums[N-1]<target)continue;//太小了,以当前a,b为基
int c=b+1,d=N-1; // 以a,b为基,c指向首,d指向尾,然后c、d逐渐靠拢
while(c<d){
int sum=nums[a]+nums[b]+nums[c]+nums[d];
if(sum>target){
d--;
while(c<d && nums[d]==nums[d+1]) d--;//跳过重复
}else if(sum<target){
c++;
while(c<d && nums[c]==nums[c-1]) c++;//跳过重复
}else{
result.push_back({nums[a],nums[b],nums[c],nums[d]});//得到一个解
d--;
while(c<d && nums[d]==nums[d+1]) d--;//跳过重复
c++;
while(c<d && nums[c]==nums[c-1]) c++;//跳过重复
}
}
}
}
return result;
}
};