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

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

Note:

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

    A solution set is:
    (-1, 0, 1)
    (-1, -1, 2)
本题首先确定一个元素,随后在剩余元素中找和为固定值的两个元素,这可以采用twoSum中的思路。本题的难点在于如何排除重复的情况,并且在排除重复时不能把正确的情况也排除掉。
功能测试用例:{-1,0,0,1,1,2,-1,-4}
特殊测试用例:{},{0},{0,1},{0,0,0,0,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> > threeSum(vector<int> &num) 
	{

		vector<vector<int>> vvnResult;
		vector<int> vnMiddle(3);
		if (num.size() < 3)//如果输入向量少于3个元素,则返回空向量
		{
			return vvnResult;
		}
		int nBegin, nEnd, nRemain;
		FastSort(num,0,num.size()-1);//对输入向量快速排序
		for (int nTemp = 0; nTemp < num.size() - 2; nTemp++)//遍历排序后从第一个到倒数第三个元素
		{
			if (nTemp > 0 && num[nTemp] == num[nTemp - 1])//如果当前元素与前一个元素重复,则跳出本次循环继续下一次循环
				continue;
			nRemain = 0 - num[nTemp];
			nBegin = nTemp + 1;
			nEnd = num.size() - 1;
			while (nBegin < nEnd)
			{
				if (num[nBegin] + num[nEnd] == nRemain)//判断三个元素的和等于0
				{
					if (nBegin != nTemp + 1 && num[nBegin] == num[nBegin - 1])//去重复情况
					{
						nBegin++;
					}
					else if (nEnd != num.size() - 1 && num[nEnd] == num[nEnd + 1])//去重复情况
					{
						nEnd--;
					}
					else
					{
						vnMiddle[0] = num[nTemp];
						vnMiddle[1] = num[nBegin];
						vnMiddle[2] = num[nEnd];
						vvnResult.push_back(vnMiddle);
						nBegin++;
						nEnd--;
					}
				}
				else if (num[nBegin] + num[nEnd] < nRemain)
				{
					nBegin++;
				}
				else
				{
					nEnd--;
				}
			}
		}
		return vvnResult;
	}
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值