和大神们学习每天一题(leetcode)-4Sum

Given an array S of n integers, are there elements abc, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.

Note:

  • Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d)
  • The solution set must not contain duplicate quadruplets.
For example, given array S = {1 0 -1 0 -2 2}, and target = 0.

    A solution set is:
    (-1,  0, 0, 1)
    (-2, -1, 1, 2)
    (-2,  0, 0, 2)
本题是在一个整数数组中查找和为目标值的四个元素,算法思想与2Sum和3Sum类似。
功能测试用例:{1,0,-1,0,-2,2},0
特殊测试用例:{},0;{0},0;{0,0},0;{0,0,0},0;{1,1,1,0,0,0,-1,-1,-1,0,-2,2,2,2},0
代码如下:
class Solution
{
public:
	void FastSort(vector<int> &vsNumber, int nBegin, int nEnd)//快速排序
	{
		if (nBegin >= nEnd)
			return;
		int nPos1 = nBegin;
		int sNMiddle = vsNumber[nEnd], sNChange;
		for (int nPos2 = nBegin; nPos2 < nEnd; nPos2++)
		{
			if (vsNumber[nPos2] < sNMiddle)
			{
				sNChange = vsNumber[nPos1];
				vsNumber[nPos1] = vsNumber[nPos2];
				vsNumber[nPos2] = sNChange;
				nPos1++;
			}
		}
		vsNumber[nEnd] = vsNumber[nPos1];
		vsNumber[nPos1] = sNMiddle;
		FastSort(vsNumber, nBegin, nPos1 - 1);
		FastSort(vsNumber, nPos1 + 1, nEnd);
	}
	vector<vector<int> > fourSum(vector<int> &num, int target)
	{
		vector<vector<int>> vvnResult;
		vector<int> vnMiddle(4);
		if (num.size() < 4)
			return vvnResult;
		FastSort(num,0,num.size()-1);//快速排序
		int nBegin, nEnd, nRemain;
		for (int nTemp1 = 0; nTemp1 < num.size() - 3; nTemp1++)//确定第一个数的位置
		{
			if (nTemp1 != 0 && num[nTemp1] == num[nTemp1 - 1])//去重复
				continue;
			for (int nTemp2 = nTemp1 + 1; nTemp2 < num.size() - 2; nTemp2++)//确定第二个数的位置
			{
				if (nTemp2 != nTemp1 + 1 && num[nTemp2] == num[nTemp2 - 1])//去重复
					continue;
				nBegin = nTemp2 + 1;
				nEnd = num.size() - 1;
				nRemain = target - num[nTemp1] - num[nTemp2];//简单前两个数后的剩余值
				while (nBegin < nEnd)
				{
					if (nBegin != nTemp2 + 1 && num[nBegin] == num[nBegin - 1])//去重复
					{
						nBegin++;
					}
					else if (nEnd != num.size() - 1 && num[nEnd] == num[nEnd + 1])//去重复
					{
						nEnd--;
					}
					else//根据当前四个数的和确定后两个数的位置
					{
						if (num[nBegin] + num[nEnd] > nRemain)
						{
							nEnd--;
						}
						else if (num[nBegin] + num[nEnd] < nRemain)
						{
							nBegin++;
						}
						else
						{
							vnMiddle[0] = num[nTemp1];
							vnMiddle[1] = num[nTemp2];
							vnMiddle[2] = num[nBegin];
							vnMiddle[3] = num[nEnd];
							vvnResult.push_back(vnMiddle);
							nEnd--;
							nBegin++;
						}
					}
				}
			}
		}
		return vvnResult;
	}
};







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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值