三数之和

给你一个包含n个整数的数组nums,判断nums中是否存在三个元素a,b,c,使得a + b + c = 0?请你找出所有和为0且不重复的三元组。

注意:答案中不可以包含重复的三元组。

提示:

  • 0 <= nums.length <= 3000
  • -10^5 <= nums[i] <= 10^5

15.三数之和

又到了爷最爱的去重环节

感觉提到去重就离不开排序,让这些蛇鼠一窝相同的元素放在一起,会比较好处理。

首先遍历第一个元素,如果第一个元素就大于0,那么后续肯定无法组合出和为0的数组,直接返回答案就行。

为了去重,如果已经开始列举第一个元素了,且和之前列举的相同,则continue。

然后开始求第二、三个元素,弄两个指针left和right(小黎这里直接用的j和k),初始化left为第一个元素的后一个指针,right为数组的最后一个。

由于这里对第二、三个元素的查找是并列的,所以从两端向中间找。如果当前加和大了,就左移right;如果小了,就右移left。所以在进入第二重循环前定义right,并且在第二重循环中right的值只减不增。当left和right重合的时候,~就说明我们回不去了~~就说明对于当前的第一个元素,已经没有更多的解了,直接break即可。

要注意,这里对于第二个元素也是有去重的,和第一个元素的去重思路相同,不再赘述啦。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> ans;
if(nums.empty() || nums.size() < 3){
return ans;
}
sort(nums.begin(), nums.end());
int n = nums.size();
for(int i = 0; i < n; ++i){
if(nums[i] > 0){
return ans;
}
if(i > 0 && nums[i] == nums[i - 1]){
continue;
}
int k = n - 1;
for(int j = i + 1; j < n; ++j){
if(j > i + 1 && nums[j] == nums[j - 1]){
continue;
}
while(j < k && nums[i] + nums[j] + nums[k] > 0){
k--;
}
if(j == k){
break;
}else if(nums[i] + nums[j] + nums[k] == 0){
ans.push_back({nums[i], nums[j], nums[k]});
}
}

}
return ans;
}
};
Contents
|