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)
给定数组,求解一个三元组,是元素相加为零,且三元组不能重复,并且有序。
思路如下:
先排序,固定第一个指针指向开头,第二个指针指向后一个元素,第三个指针指向最后一个元素。
让这三个元素相加,如果结果大于零,让最后一个元素向前移动,再次求和,反之亦然。但要确保第三个元素在第二个元素后面。
这样依次添加进向量中即可,只要保证三个指针的顺序不乱就能保证三元组有序。怎么确保不重复,也就是确保三元组都不相同。
这是个需要着重考虑的问题,很绕,本题的难点就在这里。顺着下面的代码走一遍就能很清楚的知道了。
<span style="font-size:18px;"> class Solution {
public: vector<vector<int>> threeSum(vector<int> &num) {
vector<vector<int> > v;
if(num.size()<3)//不足以构成三元组
return v;
sort(num.begin(),num.end());
for(vector<int>::size_type i = 0;i<num.size()-2;i++)
{
if(num[i]>0) break;//首元素大于零,那么三个元素求和肯定大于零,不满足条件。序列是有序的
int j = i+1,k = num.size()-1;
while(j<k)
{
if (num[i] + num[j] > 0) //同上
break;
if (num[j] + num[k] < -num[i])
++j;
else if (num[j] + num[k] > -num[i])
--k;
else
{
vector<int> temp;
temp.push_back(num[i]);
temp.push_back(num[j]);
temp.push_back(num[k]);
v.push_back(temp);
while(j<k&&num[j] == num[j+1]) j++;//这都是要去重
while(k>j&&num[k] == num[k-1]) k--;
j++;
k--;
}
while(i<num.size()-2&&num[i] == num[i+1]) ++i;//三个指针都需要去重
}
}
return v;
}
};</span>