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)
注意:
遍历 a,b,c 的话,时间复杂度达不到要求,可以先排序,再使用下标 i 遍历数组(确保 num[i] != num[i-1], 以免重复), 然后在 i+1 到 length-1 之间寻找 j、k,使得 num[j] + num[k] == -num[i],在这个寻找过程中,采用两端逼近的方法(因为数组已经排好序了),即:
num[j] + num[k] > -num[i],则 k--;
num[j] + num[k] < -num[i],则 j++;
num[j] + num[k] == -num[i],此时如果是第一次则直接保存num[i],num[j],num[k], 然后 j++, k-- ; 否则需要确保 num[j] 不等于上次的 num[j](在同一个 i 的情况下),以免重复。 如果不等,则和上面的处理一样(保存num[i],num[j],num[k], 然后 j++, k-- ), 如果相等(说明已经保存了一个,再保存就重复了),则 j++,然后放弃这次保存,程序继续。
class Solution {
public:
vector<vector<int> > threeSum(vector<int> &num) {
int len = num.size();
vector<vector<int> > iveclist;
vector<int> ivec;
sort(num.begin(), num.end());
bool start = true;
for (int i = 0; i < len; i++) {
if (start) {
start = false;
}
else if (num[i] == num[i - 1]) {
continue;
}
int j = i + 1, k = len - 1, last;
bool firsttime = true;
while (j < k) {
if (num[j] + num[k] > -num[i])
k--;
else if (num[j] + num[k] < -num[i])
j++;
else {
if (firsttime) {
firsttime = false;
last = num[j];
}
else if (num[j] == last) {
j++;
continue;
}
ivec.clear();
ivec.push_back(num[i]);
ivec.push_back(num[j]);
ivec.push_back(num[k]);
iveclist.push_back(ivec);
last = num[j];
j++;
k--;
}
}
}
return iveclist;
}
};