题目描述力扣 18.四数之和
给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):
0 <= a, b, c, d < n
a、b、c 和 d 互不相同
nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。
示例 1:
输入:nums = [1,0,-1,0,-2,2], target = 0
输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
示例 2:
输入:nums = [2,2,2,2,2], target = 8
输出:[[2,2,2,2]]
思路
本题与 15.三数之和(双指针解法超详细)_白日梦想虾的博客-CSDN博客很相似,只是外层多了一层for()循环来表示第四个数
在本题中需要注意剪枝和去重,及为防止溢出进行强制类型转换(转为long)
双指针——完整代码如下(ACM模式)
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>//使用sort()函数
using namespace std;
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
//对nums进行排序
sort(nums.begin(),nums.end());
vector<vector<int> > result; //用于保存结果集
for(int i=0;i<nums.size();i++){
//一级剪枝
//由于排好了序,若nums[i]是正数且大于了target,则后面一定不能构成四元组,因此剪枝
if(nums[i]>target && nums[i]>=0){
break;
}
//对nums[i]去重
if(i>0 && nums[i]==nums[i-1]){
continue;
}
for(int k=i+1;k<nums.size();k++){
//二级剪枝
//由于排好了序,若nums[i]+nums[k]是正数且大于了target,则后面一定不能构成四元组,因此剪枝
if(nums[i]+nums[k]>target && nums[i]+nums[k]>=0){
break;
}
//对nums[k]去重
if(k>i+1 && nums[k]==nums[k-1]){
continue;
}
//建立双指针
int left=k+1;
int right=nums.size()-1;
while(right>left){
//四元组大于目标值,说明应该加入更小的数,因此right左移
if((long)nums[i]+nums[k]+nums[left]+nums[right]>target){
right--;
}
//四元组小于目标值,说明应该加入更大的数,因此left右移
else if((long)nums[i]+nums[k]+nums[left]+nums[right]<target){
left++;
}
else{//找到满足条件的四元组
result.push_back(vector<int>{nums[i],nums[k],nums[left],nums[right]});
//对right去重
while(right>left && nums[right]==nums[right-1]){
right--;
}
//对left去重
while(right>left && nums[left]==nums[left+1]){
left++;
}
right--;
left++;
}
}
}
}
return result;
}
};
int main(){
vector<int> nums;
int n=0;
while(scanf("%d",&n)){
nums.push_back(n);
if(getchar()=='\n'){
break;
}
}
int target=0;
scanf("%d",&target);
Solution solution;
vector<vector<int>> r=solution.fourSum(nums,target);
//二维数组遍历,注意第二层范围以第一维大小来确定
for(int i=0;i<r.size();i++){
for(int j=0;j<r[0].size();j++){
cout<<r[i][j]<<" ";
}
cout<<endl;
}
}