15. 3Sum
Posted midhillzhou
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了15. 3Sum相关的知识,希望对你有一定的参考价值。
Given an array nums
of n integers, are there elements a, b, c 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.
Example:
Given array nums = [-1, 0, 1, 2, -1, -4], A solution set is: [ [-1, 0, 1], [-1, -1, 2] ]
思考:1、想了很久,不知道怎么做。只能想到时间复杂度比较高的做法。在网上查到,这个3sum问题是比较经典的,其解法基于2sum。2sum问题是给定一个排好序的数组,问有哪些两个元素相加为
0。解法是一个下标指向第一个,另一个下标指向最后一个。
有如下结论及其规则:
一、如果num[1]+num[n]>0,那么2和n的和大于0,3和n的和也会大于0。等等。所以就没必要再去计算以最后一个为右边界的组合。考虑1,..,n-1这个范围内的组合,即移动后一个。
二、如果num[1]+num[n]<0,那么1和n-1的和,1和n-2的和也会小于0。等等。所以就没必要去计算以1为左边界的组合。考虑2,...,n这个范围内的组合,即移动前一个下标。
不断进行这个操作,最终遍历所有可能的组合,而不是每个组合。
3sum问题可以分解成2sum。取出数组第一个元素X,在剩下的数组里找到两数之和为-X,这就是2sum问题。
由于c语言不支持动态添加元素,所以用c++可能更方便一些,故实现如下。ps:用c语言做了一下,一直free内存那里出问题。
1 class Solution { 2 public: 3 vector<vector<int>> threeSum(vector<int>& nums) { 4 vector<vector<int> > ans; 5 int index1,index2; 6 if(nums.size()<3) return ans; 7 8 sort(nums.begin(), nums.end()); 9 10 for (int i = 0; i <= nums.size()-3; i++) { 11 if(i!=0 && nums[i-1]==nums[i]) continue; 12 13 index1 = i+1; 14 index2 = nums.size()-1; 15 /*if(i==0) { 16 index1 = 1; 17 index2 = nums.size()-1; 18 } 19 else if (i== nums.size()-1) { 20 index1 = 0; 21 index2 = nums.size()-2; 22 }else { 23 index1 = 0; 24 index2 = nums.size()-1; 25 }*/ 26 27 28 while(index1<index2) { 29 if(nums[i]+nums[index1]+nums[index2]==0) { 30 int sol[3] = { nums[i], nums[index1], nums[index2] }; 31 ans.push_back(vector<int> (sol, sol + 3)); 32 //printf("i is %d.index1 is %d.index2 is %d.\n", i,index1,index2); 33 index1++;while(nums[index1]==nums[index1-1]) index1++; 34 index2--;while(nums[index2]==nums[index2+1]) index2--; 35 }else if (nums[i]+nums[index1]+nums[index2]>0) { 36 index2--; 37 }else { 38 index1++; 39 } 40 } 41 } 42 return ans; 43 } 44 };
以上是关于15. 3Sum的主要内容,如果未能解决你的问题,请参考以下文章