四数之和leetcode

题目一:给定一个包含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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值