题目解析:
给定一个包含 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在这里是一个全局变量的引用,所以在主程序可以直接使用。
使用指针前一定要分配内存啊朋友们!一开始没有分配内存经常报错= =
还是太菜了= =