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)

         这题可谓历经坎坷,主要是现在没有使 代码最优化的一种思想!提交了很多次都是运行超时!!!思考问题的方式不是很全面,比如说这里面元素可以重复,这一点可以让代码得到很大的优化,比如说在外层循环,如果说当前的元素和前面的元素相等,则可以跳过该次循环,虽然时间复杂度没有改变,但是运行时间少了很多!还有,在内部循环,如果第一个数都已经大于零或者最后一个数都已经小于零,循环就没必要做了,因为后面都是不可能的了!这也节省了很多的运行时间。
这一题一开始的想法很简单,觉得3sum延续了2sum,但是比2sum复杂,想到可以利用2sum的思路,把其中两个数加起来然后去找另外一个数。
class Solution {
public:
	vector<vector<int> > threeSum(vector<int> &num) {
		vector<int>vec;
		vector<int>zero;
		multimap<int, int>m;
		set<vector<int>>s;
		typedef vector<int>::size_type st;
		map<int,int>::iterator pos;
		int count=0;
		sort(num.begin(),num.end());
		for (st i = 0; i < num.size(); ++i)
			m.insert(make_pair(num[i],i));
		for (st i = 0; i < num.size(); ++i)
		{
			for (st j = i + 1; j < num.size(); ++j)
			{
				const int temp = 0 - num[i] - num[j];
				count = m.count(temp);
				pos = m.find(temp);
				if (count>1)
				{
					pos = m.upper_bound(temp);
					--pos;
				}
				if (pos != m.end())
				{
					if (pos->second >j)
					{
						vec.push_back(num[i]);
						vec.push_back(num[j]);
						vec.push_back(num[pos->second]);
						//sort(vec.begin(),vec.end());
						//soluSet.push_back(vec);
						s.insert(vec);
						vec = zero;
					}
				}
			}
		}
		vector<vector<int>>soluSet(s.begin(),s.end());
		return soluSet;
	}
};

虽然问题解决了,但是OJ没有通过,当数组非常大时,运行时间会超时!并且,通用性也很差!转换思路,发现可以用左右夹逼。可是虽然用两个指针节省了时间,可是还有优化的可能性,经过一步步的优化,终于,Accepted!!!!!!!!!!!
class Solution {
public:
	vector<vector<int> > threeSum(vector<int> &num) {
		vector<vector<int>>soluSet;
		vector<int>vec;
		vector<int>zero;
		set<vector<int>>s;
		if (num.size()<3)
			return soluSet;
		sort(num.begin(),num.end());
		typedef vector<int>::iterator it;
		it mid;
		it last;
		for (it start = num.begin(); start != num.end() - 1;++start)
		{
		    if (start != num.begin())
			{
				if (*start == *(start - 1))
					continue;
			}
			mid = start + 1;
			last = num.end()-1;
			while ( mid < last)
			{
				if (*start>0 || *last < 0)
					break;
				if ((*start + *mid + *last) == 0)
				{
					vec.push_back(*start);
					vec.push_back(*mid);
					vec.push_back(*last);
					s.insert(vec);
					++mid;
					--last;
					vec = zero;
				}
				else if ((*start + *mid + *last) < 0)
				{
					++mid;
				}
				else
				{
					--last;
				}
			}
		}
		vector<vector<int>>solutionSet(s.begin(), s.end());
		return solutionSet;
	}
};





Discuss

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值