题目 英文 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],
1
2
3
4
5
A solution set is:
[
  [-1, 0, 1],
  [-1, -1, 2]
]
中文 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
1
2
3
4
[
  [-1, 0, 1],
  [-1, -1, 2]
]
思路 
对数据进行排序(将三数之和转化为两数之和,减少时间复杂度) 
遍历,取当前节点以及当前节点右边非重复两个值(这里利用双指针),比对三个值的和是否等于0。 
因为比对的结果是0,且除当前节点外的两个节点都大于当前节点,所以如果当前节点大于0,则停止遍历原思路 暴力循环寻找最优解,但是时间复杂度变成n^3,会超时。优化思路  
首先对数组进行排序(最好快排) 
循环数组,当前节点为i 
定义两个指针 j (j=i+1)、 k (k=numssize-1),依据条件(nums[j] + nums[j] + nums[k] == 0)遍历寻找最优解。 
如果最小节点i > 0,则无需继续循环。 
 
代码 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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
void  bubbleSort (int  *nums, int  lenNums)  
    int  i, j;
    int  tmp;
    int  flag = 1 ;
    for  (i = 0 ; i < lenNums; i++) {
        for  (j = 0 ; j < lenNums - 1 ; ++j) {
            if  (nums[j + 1 ] < nums[j]) {
                tmp = nums[j + 1 ];
                nums[j + 1 ] = nums[j];
                nums[j] = tmp;
                flag = 0 ;
            }
        }
        if  (flag == 1 ) {
            break ;
        }
    }
}
 * Return an array of arrays of size *returnSize.
 * Note: The returned array must be malloced, assume caller calls free().
 */
int  **threeSum (int  *nums, int  numsSize, int  *returnSize)  
    int  i, j, k, m;
    int  **ret = malloc (sizeof (int  ) * (numsSize*(numsSize-1 )*(numsSize-2 ))/6 );
    *returnSize = 0 ;
    bubbleSort(nums, numsSize);
    for  (i = 0 ; i < numsSize; i++) {
        if  (i > 0  && nums[i - 1 ] == nums[i]) {
            continue ;
        }
        if (nums[i] > 0 )
        {
            break ;
        }
        j = i + 1 ;
        k = numsSize - 1 ;
        while  (k > j) {
            if  (nums[j] + nums[k] + nums[i]== 0 ) {
                ret[*returnSize] = (int  *) malloc (sizeof (int ) * 3 );
                ret[*returnSize][0 ] = nums[i];
                ret[*returnSize][1 ] = nums[j];
                ret[*returnSize][2 ] = nums[k];
                j++;
                k--;
                (*returnSize)++;
                while  (j < k && nums[j] == nums[j - 1 ]) {
                    j++;
                }
                while  (j < k && nums[k] == nums[k + 1 ]) {
                    k--;
                }
                continue ;
            }
            if  (nums[j] + nums[k] + nums[i] > 0 ) {
                k--;
                continue ;
            }
            if  (nums[j] + nums[k] + nums[i] < 0 ) {
                j++;
                continue ;
            }
        }
    }
    return  ret;
}