看到这道题的第一想法是暴力求解,三个循环,但是应该时间上通不过吧,所以就没试。
第二种方法有点类似前面的第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;
}