给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 请你返回所有和为 0 且不重复的三元组
注意:答案中不可以包含重复的三元组
示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0
不同的三元组是 [-1,0,1] 和 [-1,-1,2]
注意,输出的顺序和三元组的顺序并不重要
示例 2:
输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0
示例 3:
输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0
代码和思路都写在下面了
/**
* 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(const void *a,const void *b)
{
return (*(int*)a-*(int*)b);
}
int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
//初始空间 因为不知道一维数组的实际空间大小
int basement=10000;
//开辟一个二维数组用于存放一维数组以便计算sum是否为0且i j k不重复
int**res=(int**)malloc(sizeof(int*)*basement);
//升序排序
*returnColumnSizes=(int*)malloc(sizeof(int)*basement);
*returnSize=0;
qsort(nums,numsSize,sizeof(int),cmp);
int i=0;int j=0;int k=0;
for(i=0;i<numsSize;i++)
{
if(i>0&&nums[i]==nums[i-1])
continue;
j=i+1;
k=numsSize-1;
while(j<k)//升序数组 如果大于k就跳出循环
{
int sum=nums[i]+nums[j]+nums[k];
if(sum==0)
{
res[*returnSize]=(int*)malloc(sizeof(int)*3);
(*returnColumnSizes)[*returnSize]=3;
res[*returnSize][0]=nums[i];
res[*returnSize][1]=nums[j];
res[*returnSize][2]=nums[k];
(*returnSize)++;
//二维数组存放数据
//那个returnColumnSizes是用来干嘛的我不清楚
//然后就是由于一维数组大小不确定 可能有越界的情况
//realloc一个空间 增大二维数组的空间
if(*returnSize==basement){
basement*=2;
res=(int**)realloc(res,sizeof(int*)*basement*2);
*returnColumnSizes=(int*)realloc(*returnColumnSizes,sizeof(int)*basement);
}
//题目要求去除重复元素
int nums1=nums[j];int nums2=nums[k];
while(nums[j]==nums1&&j<k)
{
j++;
}
while(nums[k]==nums2&&j<k)
{
k--;
}
}
//当sum三数之和小于0时 j往右移动再找
else if(sum<0){
j++;
}
//当sum三数之和大于0时 k往左移动再找
else{
k--;
}
//然后当sum<0的时候 j往后移动++ 因为升序
//else k往前移动--
}
}
return res;
}