题面

Given an array nums of n integers, are there elements abc in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

Note: The solution set must not contain duplicate triplets.

给定数组,找出其中不重复三个和为0的元素集合。

样例

1. Given array nums = [-1, 0, 1, 2, -1, -4],
solution set is:
[
  [-1, 0, 1],
  [-1, -1, 2]
]
2. Given array nums = [0, 0, 0],
solution set is:
[
  [0, 0, 0]
]
note: this example may cause something wrong!
(heap overflow? Need you to try it.)

思路

按照我以往的傻瓜思路,暴力来解决的话,time complexity will be O(n3),that's fool.

这里参考了(抄)一个简单易于理解的solution 👉  C++ two-pointes solution

1. 不可避免地要遍历数组;

2. 固定一个元素i,通过两点法去[i+1, size()-1]中搜索另外两个数字;两点法在那个“盛最多的水”中已经见过了。

3. 若找到,就将三数集合vector<int> {i, l, r}压入结果集vector<vector<int>> res中; 

(二维vector,怎么压入一行元素呢? res.push_back(vector<int> {...}) )

Note : 怎么才能避免出现重复呢?

处理前,先对数组进行排序,而后在处理过程中,遇到相同的i, l, r 跳过即可。

源码

 1 class Solution {
 2 public:
 3     vector<vector<int>> threeSum(vector<int>& nums) {
 4         vector<vector<int>> res;
 5         sort(nums.begin(), nums.end());
 6         for(int i=0; i<nums.size(); i++)
 7         {
 8             if(i>0 && nums[i]==nums[i-1])
 9                 continue;
10             int l = i+1, r = nums.size()-1;
11             while(l < r)
12             {
13                 int sum = nums[i] + nums[l] + nums[r];
14                 if(sum > 0)
15                     r--;
16                 else if(sum < 0)
17                     l++;
18                 else
19                 {
20                     res.push_back(vector<int> {nums[i], nums[l], nums[r]});
21                     //防止重复
22                     while(l+1 < nums.size() && nums[l] == nums[l+1]) l++;
23                     while(r-1 >= 0 && nums[r] == nums[r-1]) r--;
24                     l++; r--;
25                 }
26             }
27         }
28         return res;  
29     }
30 };