描述
给出一个有n个元素的数组S,S中是否有元素a,b,c满足a+b+c=0?找出数组S中所有满足条件的三元组。
数据范围:0≤n≤10000≤n≤1000,数组中各个元素值满足 ∣val∣≤100∣val∣≤100
空间复杂度:O(n2)O(n2),时间复杂度 O(n2)O(n2)
注意:
- 三元组(a、b、c)中的元素必须按非降序排列。(即a≤b≤c)
- 解集中不能包含重复的三元组。
class Solution {
public:
vector<vector<int> > threeSum(vector<int>& num) {
// write code here
//先排序
//再使用对撞双指针
//去重:确保三个数不重复,先取出第一个数,循环找到能和这个数组合的数组,再无重合的取出下一个数,再循环找
//!这里要注意后两个指针不能往前找,跟三个数任意组合一个原理,往前找会重复!
vector<vector<int>> ans;
if (num.size() < 3)return ans;
sort(num.begin(), num.end());
for (int i = 0; i < num.size() - 2; i++) {
if (num[i] == num[i - 1] && i)continue;
int l = i + 1, r = num.size() - 1;
while (l < r) {
if (num[l] + num[r] == -num[i]) {
ans.push_back({num[i], num[l], num[r]}); //vector可以直接插入数组
while (num[l] == num[l + 1] && l + 1 < r)l++;
while (num[r] == num[r - 1] && r - 1 > l)r--;
l++, r--;//这里还要++的原因是,这里找的是这个数和它后一个数不一样的位置,++就是把当前数变成它的后一个数
} else if (num[l] + num[r] > -num[i]) {
r--;
} else l++;
}
}
return ans;
}
};
总结:会使用双指针,就是多两个下标指向,注意vector可以直接插入数组,注意这里后面两个指针必须在取的元素后面,不能比它小。这道题里面有很多细节,比较难。