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的主要内容,如果未能解决你的问题,请参考以下文章

15. 3Sum

15. 3Sum

15. 3Sum

leetcode 15 3Sum

[leetcode][15] 3Sum

15. 3Sum