15. 三数之和
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
示例 2:
输入:nums = []
输出:[]
示例 3:
输入:nums = [0]
输出:[]
思路:
采用双指针来写,i 从最左边开始遍历,l = i + 1, r = numsSize - 1;
相当于在每个符合条件的i里面做双指针,搜索是否满足a + b + c = 0;
如果 sum > 0 则 r–;
如果 sum < 0 则 l++;
一直到 l 和 r 相遇为止
代码
最后的那个*returnColumnSizes部分的内容不太懂,是直接看的大佬申请数组的方法,搞不懂力扣代码的c数组申请
/**
* 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().
*/
// qsort排序
int cmp(const void * a, const void * b) {
int *t1 = (int*)a;
int *t2 = (int*)b;
return *t1 > *t2;
}
int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
// 存放结果的二维数组
int** result = (int**)malloc(sizeof(int*) * 20000);
int tt = 0;
// 如果数组元素小于三直接返回
if (numsSize < 3) {
*returnSize = 0;
return result;
}
qsort(nums, numsSize, sizeof(int), cmp);
for (int i = 0; i < numsSize - 2; i++) {//i < numsSize - 2 给左右指针流出空间
// 最小值大于0,一定不成立
if (nums[i] > 0) break;
// 去重
if (i > 0 && nums[i] == nums[i - 1]) continue;
int l = i + 1, r = numsSize - 1;
while (l < r) {
int sum = nums[i] + nums[l] + nums[r];
if (sum > 0) r--;
else if (sum < 0) l++;
else {
int* ans = (int*)malloc(sizeof(int) * 3);
ans[0] = nums[i];
ans[1] = nums[l];
ans[2] = nums[r];
result[tt++] = ans;
// 左右指针去重
while (r > l && nums[r] == nums[r - 1]) r--;
while (l < r && nums[l] == nums[l + 1]) l++;
// 更新左右指针
l++;
r--;
}
}
}
*returnSize = tt;
*returnColumnSizes = (int*)malloc(sizeof(int) * tt);
int i;
for (i = 0; i < tt; i++) {
(*returnColumnSizes)[i] = 3;
}
return result;
}