`
jgsj
  • 浏览: 965123 次
文章分类
社区版块
存档分类
最新评论

LeetCode 3Sum 三个数和为零的集合 C++完整程序

 
阅读更多

Given an arraySofnintegers, are there elementsa,b,cinSsuch thata+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,abc)
  • 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)

掌握了这样的题的要诀就好办:

1 排序

2 前面的两个小数和后面的一个大数相加比较,如果小于0,那么前面的数往前进,增大; 如果大于0,那么后面的数往前进,减小。

3 前面的数和后面的数相遇,本次循环结束。

如本程序,第一个i可以看做是定标,j是前面的数,k是后面的数。

还有注意的就是:记得越过重复的数,以避免答案重复。当然也可以使用额外的数据结果,如set来作为容器,不允许重复数据的,或者最后使用unique处理掉重复元素。

最好还是踏踏实实用实例走一走,就可以发现很多原来无法发现的问题。用的实例最好包括特例的实例,例如空,重复,边界重复等。

可以参考leetcode:http://leetcode.com/2010/04/finding-all-unique-triplets-that-sums.html

下面带测试完整程序,方便一下初学者

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

class Solution {
public:
	vector<vector<int> > threeSum(vector<int> &num) 
	{
		sort(num.begin(), num.end());
		int i=0, j=0, k=num.size()-1;
		int num1 = 0;
		vector<int> t(3);
		vector<vector<int> > vt;

		for (; i < k-1; )
		{
			num1 = 0-num[i];
			t[0] = num[i];
			for (j = i+1, k=num.size()-1; j < k;)
			{
				if (num[j] + num[k] == num1)
				{
					t[1] = num[j++];
					t[2] = num[k--];
					vt.push_back(t);
					while (j<k && num[j] == num[j-1])
					{
						j++;
					}
					while (j<k && num[k] == num[k+1])
					{
						k--;
					}
				}
				else if (num[j] + num[k] < num1)
				{
					j++;
				}
				else
				{
					k--;
				}
			}
			i++;
			while (i<k-1 && num[i] == num[i-1])
			{
				i++;
			}
		}//for(; i<k-1; i++)
		return vt;
	}
};

int main() 
{
	vector<vector<int> > vt;
	int a[] = {-2,13,-5,-4,-7,8,0,-9,6,7,0,-4,2,1,-2,4};
	int len = sizeof(a)/sizeof(int);
	vector<int> t(a, a+len);
	Solution solu;
	vt = solu.threeSum(t);
	for (auto x:vt)
	{
		cout<<"(";
		for (auto y:x)
			cout<<y<<"\t";
		cout<<")"<<endl;
	}
	cout<<endl;

	system("pause");
	return 0;
}


2014-1-24 update

本题使用set容器防止重复会超时的,更新一下,看起来简洁点,思想是和上面的一样的:

vector<vector<int> > threeSum(vector<int> &num) 
	{
		vector<int> tmp(3);
		vector<vector<int> > rs;
		sort(num.begin(), num.end());

		for (int i = 0; i < num.size(); i++)
		{
			for (int j = i+1, k = num.size()-1; j < k; )
			{
				if (num[i]+num[j]+num[k] < 0) j++;
				else if (num[i]+num[j]+num[k] >0) k--;
				else
				{
					tmp[0] = num[i]; 
					tmp[1] = num[j]; 
					tmp[2] = num[k];
					rs.push_back(tmp);
					j++, k--;
					while (j<k && num[j] == num[j-1]) j++;
					while (j<k && num[k] == num[k+1]) k--;
				}
			}
			while (i<num.size() && num[i] == num[i+1]) i++;
		}
		return rs;
	}


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics