三数之和 c语言

题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/3sum

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。

示例:

给定数组 nums = [-1, 0, 1, 2, -1, -4],满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]

参考力扣当中的c语言题解进行编程。首先将数组进行从小到大的排序,方便快速判断当三数之和大或小时,应该向前还是向后移动数。参考c语言中的排序函数,首先对数组进行排序。


```c
 int comp(const void*a,const void*b)//用来做比较的函数。
{
    return *(int*)a-*(int*)b;
}

排序之后,设置迭代的初始值i为0,设置zuo与you作为辅助变量。为放置三元组的数组分配空间。之后进行判定,当前元素为nums[i],当值大于零时,直接退出迭代,此时i之后的元素无法与其形成三元组(都大于零),当zuo与you大小相反时,不能进行迭代。

之后进行循环,将nums[i]与nums[zuo],nums[you]相加,若值小于0,则为了增加和,令zuo 向前一个元素,反之令you退回一个元素,直到zuo与you相差1,结束循环。若找到三元组,则将三元组加入到返回数组,并且增加列数。并且为了避免重复,当zuo向后的一个元素与zuo所在的nums[zuo]相同时,退后一个元素,直到zuo 后的元素与zuo不重复,you和i也同样成立,最终得到不重复的三元组集合。


```c
int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
    *returnSize=0;  //满足条件的三元组数为0
    if(numsSize<3) return 0;   //当数组元素较少时直接返回
    int** rr = (int**)malloc(sizeof(int*) * (numsSize)*(numsSize));  //设置返回数组
    *returnColumnSizes = (int*)malloc(sizeof(int) * (numsSize)*(numsSize));   //设置列数
    int i=0,zuo=i+1,you=numsSize-1;  //设置初值和zuo,you两个辅助变量
    qsort(nums,numsSize,sizeof(int),comp);  //调用排序函数
    while((i<(numsSize-2))&&(nums[i]<=0))   //当前元素大于零时直接输出,因为剩余可以匹配的数都为正
    {
        zuo=i+1;
        you=numsSize-1;
        while(zuo<you)   //设置判定条件
        {
            if(nums[i]+nums[zuo]+nums[you]<0)  //若当前和较小,需要加上一个更大的数,下面同理
            {
                zuo++;
            }
             else if(nums[i]+nums[zuo]+nums[you]>0)
            {
                you--;
            }
            else
            {
                rr[*returnSize] = (int*)malloc(sizeof(int) * 3);  //获得三元组,给返回数组分配空间
                (*returnColumnSizes)[*returnSize] = 3;  //列数为3
                rr[*returnSize][0]=nums[i];   //将三元组输入数组
                rr[*returnSize][1]=nums[zuo];
                rr[*returnSize][2]=nums[you];
                (*returnSize)++;    //行数增加,三元组数增加
                while(nums[zuo]==nums[++zuo]&&zuo<you)  {}  //当含有重复项时,跳过重复项进行迭代
                while(nums[you]==nums[--you]&&zuo<you)  {}
            }
        }
        while(nums[i]==nums[++i]&&(i<(numsSize-2)))  {}  //当i对应的数组元素重复时,跳过
    }
    return rr;  //返回三元数组集合
}

在写代码时,要注意边界条件的设置,避免出现调用参数时超出数组范围。

发布了7 篇原创文章 · 获赞 0 · 访问量 138

猜你喜欢

转载自blog.csdn.net/qq_44183026/article/details/104662894