《leetCode》:3Sum

来源:互联网 发布:人工智能应用文献综述 编辑:程序博客网 时间:2024/05/17 02:08

题目

Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.Note:Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)The solution set must not contain duplicate triplets.    For example, given array S = {-1 0 1 2 -1 -4},    A solution set is:    (-1, 0, 1)    (-1, -1, 2)

方法一

暴力搜索法,利用三个for循环进行遍历,时间复杂度为O(n^3)

实现代码如下:

#include<stdio.h>#include<stdlib.h>#include<string.h> /** * Return an array of arrays of size *returnSize. * Note: The returned 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) {    if(nums==NULL||numsSize<3){        return NULL;    }    int nn=(numsSize)*(numsSize-1)*(numsSize-2)/6;    int **result=(int **)malloc((nn)*sizeof(int *));    int index=0;    for(int i=0;i<numsSize-2;i++){        for(int j=i+1;j<numsSize-1;j++){            for(int k=j+1;k<numsSize;k++){                if(nums[i]+nums[j]+nums[k]==0){                    //记录下来                    result[index]=(int *)malloc(3*sizeof(int));                    if(result[index]==NULL){                        exit(EXIT_FAILURE);                    }                     //将这三个数进行排序                    result[index][0]=nums[i];                    result[index][1]=nums[j];                    result[index][2]=nums[k];                    qsort(result[index],3,sizeof(result[index][0]),cmp);                    //检查下result有没有重复的                    for(int i1=0;i1<index;i1++) {                        if(result[i1][0]==result[index][0]&&result[i1][1]==result[index][1]&&result[i1][2]==result[index][2]){                            free(result[index]);                            result[index]=NULL;                            index--;                        }                    }                    index++;                 }            }        }    }    *returnSize=index;    return result;}int main(void){    int n;    while(scanf("%d",&n)!=EOF&&n>=3){        int *arr=(int *)malloc(n*sizeof(int ));        if(arr==NULL){            exit(EXIT_FAILURE);        }        for(int i=0;i<n;i++){            scanf("%d",arr+i);        }        int returnSize=0;        int **result=threeSum(arr,n,&returnSize);        for(int i=0;i<returnSize;i++){            int *temp=(result[i]);            for(int j=0;j<3;j++){                printf("%d   ",temp[j]);            }            printf("\n");        }        for(int i=0;i<returnSize;i++){            free(result[i]);            result[i]=NULL;        }    }    return 0;}

本来只想看下这个暴力搜索法时间复杂度为O(n^3),能不能AC,没想到居然AC了。
AC结果如下:

从结果可以看出:运行时间相当高;因此,需要寻找更好的方法。

方法二

第一步:先对数组进行排序
第二步:将3Sum转化为2Sum来进行求解即可

实现代码如下:

#include<stdio.h>#include<stdlib.h>#include<string.h> /** * Return an array of arrays of size *returnSize. * Note: The returned 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) {    if(nums==NULL||numsSize<3){        return NULL;    }    int nn=(numsSize)*(numsSize-1)*(numsSize-2)/6;    int **result=(int **)malloc((nn)*sizeof(int *));    //先对nums进行排序    qsort(nums,numsSize,sizeof(nums[0]),cmp);     int index=0;    for(int i=0;i<numsSize;i++){        int begin=i+1;        int end=numsSize-1;        while(begin<end){//借助于2Sum的方法            int dif=nums[i]+nums[begin]+nums[end];            if(dif==0){//找到精确的组合,则进行保存                     result[index]=(int *)malloc(3*sizeof(int));                    if(result[index]==NULL){                        exit(EXIT_FAILURE);                    }                     //将这三个数进行排序                    result[index][0]=nums[i];                    result[index][1]=nums[begin];                    result[index][2]=nums[end];                    //检查下result有没有重复的                    for(int i1=0;i1<index;i1++) {                        if(result[i1][0]==result[index][0]&&result[i1][1]==result[index][1]&&result[i1][2]==result[index][2]){                            free(result[index]);                            result[index]=NULL;                            index--;                        }                    }                    index++;                     begin++;//             } //通过dif的符号在改变begin和end,使结果更加逼近与target             else if(dif<0){                                 begin++;                }            else{//decrease value                    end--;            }        }    }               *returnSize=index;    return result;}int main(void){    int n;    while(scanf("%d",&n)!=EOF&&n>=3){        int *arr=(int *)malloc(n*sizeof(int ));        if(arr==NULL){            exit(EXIT_FAILURE);        }        for(int i=0;i<n;i++){            scanf("%d",arr+i);        }        int returnSize=0;        int **result=threeSum(arr,n,&returnSize);        for(int i=0;i<returnSize;i++){            int *temp=(result[i]);            for(int j=0;j<3;j++){                printf("%d   ",temp[j]);            }            printf("\n");        }        for(int i=0;i<returnSize;i++){            free(result[i]);            result[i]=NULL;        }    }    return 0;}

AC结果如下:从结果可以看出,这次的运行时间就缩短到64ms了,有了很大的改进

1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 遇见家里来嫌疑人员怎么办 老滚5老婆死了怎么办 美化包安装之后闪退怎么办 蕉下的伞坏了怎么办 苹果7通话音质特别差怎么办 雨伞的伞骨坏了怎么办 雨伞的铁丝掉了怎么办 手机银行验证码忘了怎么办 应用安装验证码忘了怎么办 大王卡激活码找不到了怎么办 信用卡的激活码找不到怎么办 育碧账号忘了怎么办 uplay八折券丢了怎么办 不小心按到了育碧解绑怎么办 台式电脑连不上网怎么办 重装系统也安装不了cad怎么办 染发灰色偏绿了怎么办 vgm数据填错了怎么办 克里格插值 不符合正态分布怎么办 克里金插值无效的输出范围怎么办 穿完臭袜子要洗手吗不洗怎么办 超敏c反应蛋白117怎么办 钢铁雄心4无模板怎么办 登录 新浪微博登录异常怎么办 微博授权失败怎么办qq uc微博授权失败怎么办 苹果手机无线网坏了怎么办 小米手机wife信号不好怎么办 微博出错了c403怎么办 微信客服没人接怎么办 安装包解析错误怎么办平板 苹果手机新浪免费邮箱用不了怎么办 苹果手机老是弹跳邮箱登陆怎么办 qq长时间不登录上不了怎么办 父母不会说英语怎么办英国签证 美军舰真来台湾怎么办 现役军人回家探亲和人打架怎么办 对四六不懂的人怎么办 赌球小2.5进3球怎么办 皮肤旧伤黑色斑怎么办 小米5c网络不好怎么办