1. 程式人生 > >LeetCode 3Sum 三個數和為零的集合 C++完整程式

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處理掉重複元素。

最好還是踏踏實實用例項走一走,就可以發現很多原來無法發現的問題。用的例項最好包括特例的例項,例如空,重複,邊界重複等。

下面帶測試完整程式,方便一下初學者

#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;
	}