15. 3Sum

Tags

  1. Array
  2. Two Pointers

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: 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]
]
1
2
3
4
5
6

题意:

给定一个拥有n个整数的数组S,其中有元素a,b,c在数组S中可以做到a + b + c = 0?在数组中找到所有和为0的三个数。

分析:

由题意可知,我们需要找到数组中的三个数相加为0,最直接的方法就是冒泡进行三层循环,但是必须做条件限定,不然时间会超时达到O(n3)。因此,在每一层循环中,如果数大于0,就退出循环。同时,题目要求,返回的数组不能重复,所以在循环过程中还要做去重工作。最后在循环最里层找到满足要求的数字存入数组中即可。

思路:

  1. 对数组进行升序排序
  2. 做三层冒泡循环,每层中的变量亦或者相加变量大于0的时候,该层循环退出;如果每层循环中的前后数字一直,则跳过,以达到去重目的。最后在循环里层,找到满足要求的数字存入数组中。
  3. 注意边界情况,如:当数组小于3的时候

Js实现:

复杂度

时间复杂度O(n2)

方法 #1

/**
 * @param {number[]} nums
 * @return {number[][]}
 */

var threeSum = function(nums) {
 let result = [];
 if (nums.length < 3 || nums === null) {
    return result;
 }

 nums.sort(function(a,b) {
   return a - b;
 });

 for (let i = 0; i < nums.length; i++) {
   if (nums[i] > 0) break;
   for (let j = i + 1; j < nums.length; j++) {
     if (nums[i] + nums[j] > 0 && nums[j] > 0) break;
       for (let k = j + 1; k < nums.length; k++) {
         if (nums[i] + nums[j] + nums[k] === 0) {
           let each = [];
           each.push(nums[i]);
           each.push(nums[j]);
           each.push(nums[k]);
           result.push(each);
           each = [];
         }
         while (1 + k < nums.length && nums[k] == nums[k + 1])
           k++;
         }
      while (j + 1 < nums.length && nums[j] == nums[j + 1])
       j++;
      }
   while (i + 1 < nums.length && nums[i] == nums[i + 1])
     i++;
   }
 return result;
};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

方法 #2

var threeSum = function(nums) {
    let result = [];
    if(nums === null || nums.length<3) return result;
      nums.sort(function(a,b){
      return a - b;
    });
  for(let i=0; i<nums.length-2; i++){
    if(i===0 || nums[i] > nums[i-1]){
      let j=i+1;
      let k=nums.length-1;
    while(j<k){
      if(nums[i]+nums[j]+nums[k]===0){
      let l = [];
      l.push(nums[i]);
      l.push(nums[j]);
      l.push(nums[k]);
      result.push(l);
      l = [];
      j++;
      k--;
    //去重
    while(j<k && nums[j]==nums[j-1])
      j++;
    while(j<k && nums[k]==nums[k+1])
      k--;
    }else if(nums[i]+nums[j]+nums[k]<0){
      j++;
    }else{
      k--;
    }
   }
  }
 }
   return result;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
上次更新: 2018-9-11 10:36:19