[leetcode] 3Sum
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)
即给定一个数组S,输出S中的三个元素使得之和为0,且每个元组中元素从小到大的排列,且不重不漏。
为了保证不重不漏,首先把数组S进行排序。其中数组S的大小为N。若使用三重for循环则会超时。
方法是使用三个指针i,p,q对数组进行遍历,其中
- i从[0,N-2)进行正向遍历,代表三元组的第一个元素。
- p从(i,N-1)进行正向遍历,代表三元组的第二个元素。
- q从(N,p)进行反向遍历,代表三元组中的第三个元素。
当sum>0时,说明和过大,则q--,当sum<0时,说明和过小p++,若sum==0,则保存到结果中。
需要注意的是,为了保证三元组不重复,要判断当前指向的元素与上一次指向的元素的值是否相同,若相同说明已经遍历过了,continue即可。
代码如下:
1 class Solution { 2 public: 3 vector<vector<int> > threeSum(vector<int> &num) { 4 5 vector<vector<int> > res; 6 7 if( num.size() < 3 ) 8 { 9 return res; 10 } 11 12 sort(num.begin(), num.end()); 13 14 for( int i = 0 ; i < num.size()-2 ; i++ ) 15 { 16 if( i > 0 && num[i] == num[i-1] ) 17 { 18 continue; 19 } 20 int p = i + 1; 21 int q = num.size() - 1; 22 while( p < q ) 23 { 24 25 if( p > i + 1 && num[p] == num[p-1] ) 26 { 27 p++; 28 continue; 29 } 30 31 if( q < num.size()-1 && num[q+1] == num[q] ) 32 { 33 q--; 34 continue; 35 } 36 37 vector<int> sumtmp; 38 39 int sum = num[i] + num[p] + num[q]; 40 41 if( sum == 0 ) 42 { 43 sumtmp.push_back(num[i]); 44 sumtmp.push_back(num[p]); 45 sumtmp.push_back(num[q]); 46 res.push_back(sumtmp); 47 p++; 48 } 49 50 if( sum < 0 ) 51 { 52 p++; 53 } 54 55 if( sum > 0 ) 56 { 57 q--; 58 } 59 } 60 } 61 } 62 };