题目一:给定一个包含n个整数的数组nums和一个目标值target,判断nums中是否存在4个元素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]].
#include<iostream>
#include<algorithm>
#include<vector>
#include<unordered_map>
using namespace std;
class Solution {
vector<vector<int>> ret;
vector<int> mynums, subans;
int tar, numSize;//tar:目标值 numSize:数组大小
public:
vector<vector<int>> fourSum(vector<int>& nums, int target)
{
sort(nums.begin(), nums.end());
//获取当前数组的长度
numSize = nums.size();
mynums = nums;
tar = target;
if (numSize < 4) return ret;
DFS(0, 0);
return ret;
}
void DFS(int low, int sum)//low: 起始遍历的下标 sum:当前需要凑出的目标值
{
//找到一个解
if (sum == tar && subans.size() == 4)
{
ret.push_back(subans);
return;
}
//寻找可能解
for (int i = low; i < numSize; i++)
{
//剪枝:当前需要找的剩余元素个数比剩余元素多,那么说明无解,返回
if (numSize - i < 4 - subans.size()) return;
if (i > low && mynums[i] == mynums[i - 1]) continue;//去重
//第三种情况的剪枝
if (i<numSize - 1 && sum + mynums[i] + mynums[i + 1] * (int)(3 - subans.size())>tar) return;
//第四种情况的剪枝
if (i < numSize - 1 && sum + mynums[i] + mynums[numSize - 1] * (int)(3 - subans.size()) < tar) continue;
//确定一个位置
subans.push_back(mynums[i]);
//去确定下一个位置
DFS(i + 1, sum + mynums[i]);
//回溯,寻找其他解
subans.pop_back();
}
}
};
vector<vector<int>> TwoPonit(vector<int> input, int target) {
int len = input.size();
sort(input.begin(), input.end());
vector<vector<int>> ret;
if (input.size() < 4) {
return ret;
}
for (int i = 0; i < len - 3; i++) {
if (i > 0 && input[i] == input[i - 1]) {
continue;
}
for (int j = i + 1; j < len - 2; j++) {
if (j > 0 && input[j] == input[j - 1]) {
continue;
}
int left = j + 1;
int right = len - 1;
while (left < right) {
int sum = input[i] + input[j] + input[left] + input[right];
if (sum < target) {
left++;
}
else if (sum > target) {
right--;
}
else {
ret.push_back({ input[i],input[j],input[left],input[right] });
left++;
right--;
while (left < right && input[left] == input[left+1]) {
left++;
}
while (left < right && input[right] == input[right - 1]) {
right--;
}
}
}
}
}
return ret;
}
题目二:给定4个包含整数的数组列表A、B、C、D,计算有多少个元组(i,j,k,l)能使A[i]+B[j]+C[k]+D[l] = 0
#include<iostream>
#include<algorithm>
#include<vector>
#include<unordered_map>
using namespace std;
//undermap查找等函数都是对key进行查找
int FourSumCount(vector<int>& a, vector<int>& b,
vector<int>& c, vector<int>& d,
int target) {
int len = b.size();
int res = 0;
unordered_map<int, int> unorder_map;
for (int i = 0; i < len; i++) {
for (int j = 0; j < len; j++) {
unorder_map[a[i] + b[j]]++;
}
}
for (int i = 0; i < len; i++) {
for (int j = 0; j < len; j++) {
if (unorder_map.count(target - c[i] - d[j])) {
res += unorder_map[target - c[i] - d[j]];
}
}
}
return res;
}