Given an array S of n integers, are there elements a, b, c 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;
}
};