此題先取一個數(shù),再在后面的數(shù)中找 2 個數(shù)的和為所取數(shù)的相反數(shù),容易得時間復雜度為 O(n^2) ,為簡化代碼編寫,我們先用 O(nlogn) 的時間對數(shù)組進行排序,再進行遍歷查找。想法的基本代碼實現(xiàn)還是比較簡單的,更重要的是要注意對于一些特殊情況的處理,包括:
三個數(shù)的組合可能在不同位置,但是這三個數(shù)數(shù)值是一樣的,對已經出現(xiàn)過的組合不能重復輸出;
選第一個數(shù)出來后,從剩余的數(shù)中篩選可能出現(xiàn)多種組合,因此找到一組可行組合時要繼續(xù)往下找;
如果所選的數(shù)大于 0 ,那么可以不再繼續(xù)查找了,因為排序的數(shù)組不可能出現(xiàn)三個大于 0 的和為 0 。
/**
* Return an array of arrays of size *returnSize.
* Note: The returned array must be malloced, assume caller calls free().
*/
int cmp(const void*a,const void*b) {return *(int*)a-*(int*)b;}
/**
* 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){
if (numsSize <= 0) return NULL;
int total = 64;
int size = 0;
int i,start,end,sum;
int ** result = (int **)malloc(sizeof(int *) * total);
for(i = 0 ;i< total; i++){
result[i] = (int *)malloc(sizeof(int)* 3);
}
qsort(nums, numsSize, sizeof(int), cmp);
for(i = 0; i < numsSize-2; ++i){
if(nums[i] > 0)
break;
if(i > 0 && nums[i] == nums[i-1]){
continue;
}
start = i + 1;
end = numsSize - 1;
while(start < end){
sum = nums[i] + nums[start] + nums[end];
if(sum == 0){
if(size > 0 && result[size-1][0] == nums[i] &&
result[size-1][1] == nums[start] && result[size-1][2] == nums[end]){
++start;
--end;
continue;
}
result[size][0] = nums[i];
result[size][1] = nums[start];
result[size][2] = nums[end];
size++;
if(size == total){
total <<= 1;
int t;
result = (int **)realloc(result,sizeof(int *) * total);
for(t = size; t < total; ++t)
result[t] = (int *)malloc(sizeof(int) * 3);
}
++start;
--end;
} else if(sum > 0){
--end;
}else{
++start;
}
}
}
*returnSize = size;
return result;
}