算法-哈希表:四数之和
在一个数组中,找到四个元素(这四个元素就是一个四元组),使其相加等于target。问在这个数组中可以找到多少组这样的元祖(四元组不可重复)?输出这些四元组。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//采用双指针解法,在三数之和的基础上再嵌套一层for循环
//对数组进行排序,通过两次for循环,left为j后的第一个值,right为最后一个值,求和,若大于0,则right--,若小于0,则left++
//a为nums[i],b为nums[j],c为nums[left],d为nums[right]
vector<vector<int>> forSum(vector<int> nums, int target){
vector<vector<int>> result;
sort(nums.begin(), nums.end());
if(nums.size() > 0){
if(nums[0] > target){ //剪枝:排序之后第一个元素大于0,则一定不会出现满足条件的四元组
return result;
}
}
for(int i = 0; i < nums.size(); i++){
//首先对i进行去重,i为0的时候不考虑,因为第0个肯定要参与比较
if(i > 0 && nums[i] == nums[i-1]){
continue;
}
for(int j = i+1; j < nums.size(); j++){
//对j去重
if(j > i+1 && nums[j] == nums[j-1]){
continue;
}
//定义left和right
int left = j+1;
int right = nums.size()-1;
//循环不变量left<right
while(left<right){
if(nums[i]+nums[j]+nums[left]+nums[right] > target){
right--;
}
else if(nums[i]+nums[j]+nums[left]+nums[right] < target){
left++;
}
else{
result.push_back(vector<int>{nums[i],nums[j],nums[left],nums[right]});
//对left和right去重
while(left<right && nums[left]==nums[left+1]){
left++;
}
while(left<right && nums[right]==nums[right-1]){
right--;
}
//同时收缩left和right
left++;
right--;
}
}
}
}
return result;
}
int main() {
vector<int> nums1 = {-1,3,1,-2,0,1,-1,3,-3};
int target;
while(cin>>target){
vector<vector<int>> result = forSum(nums1,target);
for(int i = 0; i < result.size(); i++){
for(int j = 0; j < result[i].size(); j++){
cout<< result[i][j]<<" ";
}
cout<<endl;
}
}
return 0;
}