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)
Subscribe to see which companies asked this question
- 分析:最简单的思路应该是O(n^3)也就是暴力求解:三重for循环计算出每三个字组合的结果与目标,作为一个志向的程少年我们显然不能满足于这种方法,仔细思考下有没有其他的解决办法。有没有可能把时间复杂度压缩到O(n^2)。
- 我们把数进行下排列成为有序数列:排序的时间复杂度为O(nlgn)<O(n^2),分析排序后的数列。
- 1,2,3,4,5,6,7 可以直观想到两个数的和最大值和最小值分别为8和3,对应位置为(6+7)和(1+2)定义两个指针分别从指向头i和尾j,例如查找和为9,的两个数开始时候1+7=8<9 ,这时候我们需要一个大一点的数,头指针就往后一个i+1指向2,(2+7=9)存入一个结果,这时候头尾各向相对方向前进一步,注意人(如果当前a[i]=a[i+1]),i单独向后走,同理j单独向前走)。
- 我们可以把这个问题推广下对于3nums 就是固定一个数找2num,对于4nums,就是固定一个数找3nums,以此类推,这类问题都可以同一解了。
- 代码如下
</pre><pre name="code" class="cpp">class Solution { public: vector<vector<int>> answer; void find(vector<int>& nums,int begin,int end,int target){ int i = begin,j = end; while(i<j){ if(nums[i] + nums[j] + target == 0){ vector<int> ans ; ans.push_back(target); ans.push_back(nums[i]); ans.push_back(nums[j]); answer.push_back(ans); while(i<j && nums[i] == nums[i+1]) i++; while(i<j && nums[j] == nums[j-1]) j--; i++; j--; }else if (nums[i] + nums[j] + target<0){ i++; }else if (nums[i] + nums[j] + target>0){ j--; } } } vector<vector<int>> threeSum(vector<int>& nums) { sort(nums.begin(),nums.end()); if (nums.size()<3 ) return answer; sort(nums.begin(),nums.end()); int len =nums.size(); for(int i = 0 ;i<len-2;i++){ if(i>=1){ if(i<len &&nums[i] == nums[i-1]){ continue; } } find(nums,i+1,len-1,nums[i]); } return answer; } };