15. 3Sum

这里写图片描述
看到这道题的第一想法是暴力求解,三个循环,但是应该时间上通不过吧,所以就没试。
第二种方法有点类似前面的第11题Container With Most Water,将数组先排序,开始外面一个大循环,然后j,k两个指针分别指向首和尾,如果小于0,j向右移,大于0,k向左移,等于0时保存,类似贪心算法,中间要注意重复的情况。这样时间复杂度为O(N^2)。

#include<stdio.h>
#include<stdlib.h>
int compare(const void *a,const void *b)
{
    return *(int *)a-*(int *)b;
}
int** threeSum(int* nums, int numsSize, int* returnSize) 
{
    int i,j,k,num=0;
    int **solve;
    solve=(int **)malloc(sizeof(int *)*1000);
    for(i=0;i<1000;i++)
        solve[i]=(int *)malloc(sizeof(int)*3);
    if(numsSize<3)//排除元素个数小于3
    {
        *returnSize=0;
        return solve;
    }
    qsort(nums,numsSize,sizeof(int),compare);
    for(i=0;i<numsSize;i++)
    {
        while(i>0&&i<numsSize&&nums[i]==nums[i-1])//排除重复的情况,要注意i>0;[0,0,0,0]
            i++;
        for(j=i+1,k=numsSize-1;j<k;)
        {
            if(0==nums[i]+nums[j]+nums[k])
            {
                num++;
                solve[num-1][0]=nums[i];
                solve[num-1][1]=nums[j];
                solve[num-1][2]=nums[k];
                j++;
                k--;
                while(j<k&&nums[j]==nums[j-1]&&nums[k]==nums[k+1])//排除[-2 0 0 2 2]
                {
                    j++;
                    k--;
                }
            }
            else if(nums[i]+nums[j]+nums[k]<0)
                j++;
            else
                k--;
        }
    }
    *returnSize=num;
    return solve;
}
int main()
{
    int *number,N,**result,i,j,num;
    scanf("%d",&N);
    number=(int *)malloc(sizeof(int)*N);
    for(i=0;i<N;i++)
        scanf("%d",number+i);
    result=(int **)malloc(sizeof(int *)*1000);
    for(i=0;i<5;i++)
        result[i]=(int *)malloc(sizeof(int)*3);
    result=threeSum(number,N,&num);
    for(i=0;i<num;i++)
    {
        for(j=0;j<3;j++)
            printf("%d ",result[i][j]);
        printf("\n");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值