思路:快排将数组升序排序,然后选定一个数,夹逼找到另两个数,依次遍历,注意边界条件的设定。
/**
* Return an array of arrays of size *returnSize.
* Note: The returned array must be malloced, assume caller calls free().
*/
//快排算法
void Qsort(int *a, int low, int high){
if(low > high) return;
int first = low;
int last = high;
int key = a[first];
while(first < last){
while(first < last && a[last] >= key) --last;
if(first < last) a[first] = a[last];
while(first < last && a[first] <= key) ++first;
if(first < last) a[last] = a[first];
}
a[first] = key;
Qsort(a, low, first-1);
Qsort(a, first+1, high);
}
int** threeSum(int* nums, int numsSize, int* returnSize) {
//k、l、r依次为待分析的第1、2、3个数的下标
//sum记录当前处理的三个数的和;top记录栈顶位置
int k, l, r, sum, top = -1;
int **res = (int**)malloc(sizeof(int*) * (numsSize * (numsSize-1) * (numsSize-2)) / 6);
Qsort(nums, 0, numsSize - 1);
//给定数组不足三个元素,返回为空元素
if(numsSize < 3){
*returnSize = 0;
return res;
}
for(k = 0; k < numsSize - 2; ++k){
//第一个数为正,三个数和必大于零
if(nums[k] > 0) break;
//(边界处理)跳过重复项
if(k > 0 && nums[k] == nums[k - 1]) continue;
//初始化l和r
l = k + 1;
r = numsSize - 1;
//主循环体(夹逼法)
while(l < r){
sum = nums[k] + nums[l] + nums[r];
if(sum == 0){
res[++top] = (int*)malloc(sizeof(int) * 3);
res[top][0] = nums[k];
res[top][1] = nums[l++];
res[top][2] = nums[r--];
//(边界处理)跳过重复项
while(nums[l] == nums[l - 1]) ++l;
while(nums[r] == nums[r + 1]) --r;
}
else if(sum < 0) ++l;
else --r;
}
}
*returnSize = top + 1;
return res;
}