1+ /*
2+ * 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.
3+
4+ * Note: The solution set must not contain duplicate triplets.
5+
6+ * For example, given array S = [-1, 0, 1, 2, -1, -4],
7+
8+ * A solution set is:
9+ * [
10+ [-1, 0, 1],
11+ [-1, -1, 2]
12+ * ]
13+ * Created by supercoderx on 2017/8/9.
14+ */
15+ #include <stdio.h>
16+ #include <stdlib.h>
17+
18+ void sort (int * a , int left , int right )
19+ {
20+ if (left >= right )/*如果左边索引大于或者等于右边的索引就代表已经整理完成一个组了*/
21+ {
22+ return ;
23+ }
24+ int i = left ;
25+ int j = right ;
26+ int key = a [left ];
27+
28+ while (i < j ) /*控制在当组内寻找一遍*/
29+ {
30+ while (i < j && key <= a [j ])
31+ /*而寻找结束的条件就是,1,找到一个小于或者大于key的数(大于或小于取决于你想升
32+ 序还是降序)2,没有符合条件1的,并且i与j的大小没有反转*/
33+ {
34+ j -- ;/*向前寻找*/
35+ }
36+
37+ a [i ] = a [j ];
38+ /*找到一个这样的数后就把它赋给前面的被拿走的i的值(如果第一次循环且key是
39+ a[left],那么就是给key)*/
40+
41+ while (i < j && key >= a [i ])
42+ /*这是i在当组内向前寻找,同上,不过注意与key的大小关系停止循环和上面相反,
43+ 因为排序思想是把数往两边扔,所以左右两边的数大小与key的关系相反*/
44+ {
45+ i ++ ;
46+ }
47+
48+ a [j ] = a [i ];
49+ }
50+
51+ a [i ] = key ;/*当在当组内找完一遍以后就把中间数key回归*/
52+ sort (a , left , i - 1 );/*最后用同样的方式对分出来的左边的小组进行同上的做法*/
53+ sort (a , i + 1 , right );/*用同样的方式对分出来的右边的小组进行同上的做法*/
54+ /*当然最后可能会出现很多分左右,直到每一组的i = j 为止*/
55+ }
56+ int * * threeSum (int * nums , int numsSize , int * returnSize ) {
57+ int * pItem = NULL , * * result = NULL ;
58+ int tmp , sum = 0 ;
59+ * returnSize = 0 ;
60+ if (numsSize < 3 ) {
61+ return NULL ;
62+ }
63+
64+ // 冒泡排序
65+ for (int i = 0 ; i < numsSize - 1 ; i ++ ) {
66+ for (int j = 0 ; j < numsSize - 1 - i ; j ++ ) {
67+ if (nums [j + 1 ] < nums [j ]) {
68+ tmp = nums [j ];
69+ nums [j ] = nums [j + 1 ];
70+ nums [j + 1 ] = tmp ;
71+ }
72+ }
73+ }
74+ // sort(nums,0,numsSize-1);
75+
76+ // 寻找三元组
77+ for (int i = 0 ; i < numsSize - 2 ;i ++ ){
78+ // 去除元素1的重复
79+ if (i > 0 && nums [i ]== nums [i - 1 ]){
80+ continue ;
81+ }
82+ sum = - nums [i ];
83+ int j = i + 1 ,k = numsSize - 1 ;
84+ while (j < k ){
85+ if (nums [j ]+ nums [k ]== sum ){
86+ // 加进结果列表中
87+ pItem = malloc (sizeof (int )* 3 );
88+ pItem [0 ] = nums [i ];
89+ pItem [1 ] = nums [j ];
90+ pItem [2 ] = nums [k ];
91+ (* returnSize )++ ;
92+ if (result == NULL ){
93+ result = malloc (sizeof (int * ));
94+ result [0 ] = pItem ;
95+ }else {
96+ result = realloc (result , sizeof (int * )* (* returnSize ));
97+ result [* returnSize - 1 ] = pItem ;
98+ }
99+
100+ j ++ ;
101+ k -- ;
102+ // 去除元素2和元素3的重复
103+ while (nums [j ]== nums [j - 1 ] && j < k ) j ++ ;
104+ while (nums [k ]== nums [k + 1 ] && j < k ) k -- ;
105+ }else if (nums [j ]+ nums [k ]< sum ){
106+ j ++ ;
107+ } else {
108+ k -- ;
109+ }
110+ }
111+ }
112+ return result ;
113+ }
114+
115+ void testThreeSum (){
116+ int a [6 ] = {-1 , 0 , 1 , 2 , -1 , -4 }, count = 0 ;
117+ int * * res = threeSum (a ,6 , & count );
118+ for (int i = 0 ;i < count ;i ++ ){
119+ printf ("%d, %d, %d\n" , res [i ][0 ],res [i ][1 ],res [i ][2 ]);
120+ }
121+
122+ }
0 commit comments