Leetccode 15. 三数之和(C语言快速排序+查找)

题目解析:

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

第一个想法肯定是三层循环嵌套,但是题目中的不包含重复组让我们的判断变得异常困难,所以首先进行排序排序后遇到与前一个相同的数字就跳过,嵌套的第二层循环记录剩下的首尾位置,首尾位置分别判断网中间聚拢的过程中,若下一个数字与此时一致,则跳过这个数字。

代码:

我的代码写出来鲁棒性不太好,下面借鉴了一个网上胖友的代码跟我思路一样,但写的比我好

#include <stdio.h>
#include <stdlib.h>
void quickSort(int* nums,int first,int end){
    int temp,l,r;
    if(first>=end)return;
    temp=nums[first];
    l=first;r=end;
    while(l<r){
        while(l<r && nums[r]>=temp)r--;
        if(l<r)nums[l]=nums[r];
        while(l<r && nums[l]<=temp)l++;
        if(l<r)nums[r]=nums[l];
    }
    nums[l]=temp;
    quickSort(nums,first,l-1);
    quickSort(nums,l+1,end);
} //快排代码

int** threeSum(int* nums, int numsSize, int* returnSize) {
    int i,sum,top=-1,begin,end;
    int** res=(int**)malloc(sizeof(int*)*(numsSize*(numsSize-1)*(numsSize-2))/6);
    if(numsSize<3){
        *returnSize=0;
        return res;
    }  //组内元素小于三时直接返回;
    quickSort(nums,0,numsSize-1);//快排;
    for(i=0;i<numsSize;i++){
        if(nums[i]>0)
            break;//首元素大于0,跳出for,已经查找到所有符合条件的三元组;
        if(i>0 && nums[i]==nums[i-1])continue; //与上次循环的数一样,跳过这个数,执行i++向下找;
        begin=i+1;end=numsSize-1; //固定i后在i+1/尾两处放入指针,开始循环;
        while(begin<end){
            sum=nums[i]+nums[begin]+nums[end];
            if(sum==0){
                top++;
                res[top]=(int*)malloc(sizeof(int)*3);
                res[top][0]=nums[i];res[top][1]=nums[begin];res[top][2]=nums[end];
                begin++;end--;
                while(begin<end && nums[begin]==nums[begin-1])begin++;
                while(begin<end && nums[end]==nums[end+1])end--;
            }
            else if(sum>0) end--;
            else begin++;
        } //while
    } //for
    *returnSize=top+1; //top作为计数器,即为需要返回的长度;
    return res;
}

int main()
{
    int nums[6]={1,2,0,0,-2,0};
    int *q;
    q=nums;
    int numsSize=6;
    int* returnSize;
    int **p;
    returnSize=(int*)malloc(sizeof(int*));
    p=(int**)malloc(sizeof(int*)*(numsSize*(numsSize-1)*(numsSize-2))/6);
    p=threeSum(nums,numsSize,returnSize);
    for(int i=0;i<*returnSize;i++)
    {
       for(int j=0;j<3;j++)
        {
            printf("%d ",*(*(p+i)+j));
        }
        printf("\n");

    }

    return 0;

}

returnSize在这里是一个全局变量的引用,所以在主程序可以直接使用。
使用指针前一定要分配内存啊朋友们!一开始没有分配内存经常报错= =
还是太菜了= =

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值