给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
来源:力扣(LeetCode)
快速排序 + 双指针
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
int
cmp(int *a, int *b)
{
return *a - *b;
}
int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes)
{
*returnSize = 0;
if (numsSize < 3)
{
return NULL;
}
// 利用 qsort 函数排序数组
qsort (nums, numsSize, sizeof (int), cmp);
/* 申请二维数组,只申请了大小为二维数组中所有一维数组的指针的总和的内存,
numSize代表了二维数组中所有一维数组的个数,也即二维数组的行数 */
int **ans = (int **)malloc (sizeof (int *) * (numsSize * numsSize));
*returnColumnSizes = malloc (sizeof (int) * (numsSize * numsSize));
// returnColumnSizes 是一维数组的地址
for (int i = 0; i < numsSize; i ++)
{
if (nums[i] > 0)
{
break;
}
// 查重 三指针固定其一
if (i > 0&&nums[i] == nums[i - 1])
{
continue;
}
int left = i + 1;
int right = numsSize - 1;
while (left < right)
{
int sum = nums[i] + nums[left] + nums[right];
if (sum == 0)
{
// 这里申请二维数组中的一维数组,且一维数组大小为3
ans[*returnSize] = malloc (sizeof (int) * 3);
ans[*returnSize][0] = nums[i];
ans[*returnSize][1] = nums[left];
ans[*returnSize][2] = nums[right];
// (* returnColumnSizes)[*returnSize] 是一维数组的第*returnSize个元素
(*returnColumnSizes)[*returnSize] = 3;
(*returnSize) ++;
/* 此处只能为 ++ left (right)
因为再作判断时 ++ i是先自增后判断而 i ++相反*/
while (left < right&&nums[left] == nums[++ left]);
while (left < right&&nums[right] == nums[-- right]);
// 阻止循环,查重
}
else if (sum < 0)
{
left ++;
}
else
{
right --;
}
}
}
return ans;
}