四数之和
三数之和
【题意】给定一个包含 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] ]
【解题思路】
四数之和因为target
是任意值,故不需要判断nums[k] > target
。三数之和可以通过 nums[i] > 0
就返回了,因为 0 已经是确定的数了,四数之和这道题目 target
是任意值,三数之和也可以改为任意值。对于五数、六数都是一样的解法。
四数之和的双指针解法是两层for循环nums[k] + nums[i]
为确定值,依然是循环内有left
和right
下标作为双指针,找出nums[k] + nums[i] + nums[left] + nums[right] == target
的情况,三数之和的时间复杂度是
O
(
n
2
)
O(n^2)
O(n2),四数之和的时间复杂度是
O
(
n
3
)
O(n^3)
O(n3) 。
/*四数之和*/
vector<vector<int>> fourSum(vector<int>& nums,int target){
vector<vector<int>> result; //存放结果
sort(nums.begin(),nums.end()); //排序
for(int k = 0;k < nums.size();++k){ //第一层循环
if(k > 0 && nums[k] == nums[k - 1]) //去重
continue;
for(int i = k + 1;i < nums.size();++i){ //第二层循环
if(i > k+1 && nums[i] == nums[i - 1]) //去重
continue;
int left = i + 1;
int right = nums.size() - 1;
while(right >left){
if(nums[k] + nums[i] + nums[left] + nums[right] > target){ //大于目标值
right--;
while(right > left && nums[right] == nums[right+1]) //去重
right--;
}else if(nums[k] + nums[i] + nums[left] + nums[right] < target){ //小于目标值
left++;
while(right > left && nums[left] == nums[left-1]) //去重
left++;
}else{ //等于目标值
result.push_back(vector<int> {nums[k],nums[i],nums[left],nums[right]});
while(right > left && nums[right] == nums[right-1]) //去重
right--;
while(right > left && nums[left] == nums[left - 1]) //去重
left++;
right--;
left++;
}
}
}
}
return result;
}
测试
int main(){
vector<int> v = {-1,2,-3,-5,9,0,8,1,3,-1,-1,-3,-5};
vector<vector<int>> result = fourSum(v,0);//threeSum(v);
cout << result.size() << endl;
for(auto item : result){
for(auto i : item){
cout << i << " ";
}
cout << endl;
}
return 0;
}
【参考】代码随想录