题目 英文 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,则无需继续循环。 优化后代码时间复杂度由原来的n^3变为n^2
代码 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;
}