【LeetCode刷题(数据结构与算法)】:三数之和(数组+指针+排序)

在这里插入图片描述
给你一个整数数组 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;
}

猜你喜欢

转载自blog.csdn.net/fjj2397194209/article/details/134015122