10 三数之和

15 阅读1分钟

题目

image.png

思路

  1. 找到符合要求的三元组。

  2. 对所有符合要求的三元组进行去重:去掉可能重复的。

#include<stdio.h>
#include<stdlib.h>
int cmp(const void *a,const void *b){//升序 
	return (*(int *)a- *(int *)b);
}
int **threeSum(int *nums,int numsSize,int *returnSize,int **returnColumnSizes){
	int **res=NULL;//结果集
	int resSize=0;
	*returnSize=0;
	*returnColumnSizes=NULL;
	qsort(nums,numsSize,sizeof(int),cmp);//升序排列
	
	for(int i=0; i<numsSize; i++){
		//排序后若第一个元素>0,则没有符合条件的三元组 
		if(nums[i]>0) 
			break;
		//去重 
		if(i>0 && nums[i]==nums[i-1]) 
			continue;
		
		int left=i+1;
		int right=numsSize-1;
		while(right>left){
			if(nums[i]+nums[left]+nums[right]>0)
				right--;
			else if(nums[i]+nums[left]+nums[right]<0)
				left++;
			else{
				resSize++;
				res=(int**)realloc(res,resSize*sizeof(int *));//数组扩容
				res[resSize-1]=(int *)malloc(3*sizeof(int));
				//放入三元组 
				res[resSize-1][0]=nums[i];
				res[resSize-1][1]=nums[left];
				res[resSize-1][2]=nums[right];
				//对b和c去重 
				while(right>left && nums[right]==nums[right-1])
					right--;
				while(right>left && nums[left]==nums[left+1])
					left++;
				//确定一个满足的三元组,双指针收缩
				right--;
				left++; 
			}
		}
	}
	
	*returnSize=resSize;//将结果集的行数返回,*表示解引用retureSize 
	if(resSize>0){
		*returnColumnSizes=(int *)malloc(resSize*sizeof(int));
		for(int i=0; i<resSize; i++){
			(*returnColumnSizes)[i]=3;
		}
	}
	return res;
}
int main(){
	int nums[]={-1,0,1,2,-1,4};
	int numsSize=sizeof(nums)/sizeof(nums[0]);
	int returnSize;
	int *returnColumnSizes;
	
	int **res=threeSum(nums,numsSize,&returnSize,&returnColumnSizes);
	for(int i=0; i<returnSize; i++){
		for(int j=0; j<returnColumnSizes[i]; j++)
			printf("%d ",res[i][j]);
		printf("\n");
	}
	//释放动态分配的内存
	for(int i=0; i<returnSize; i++)
		free(res[i]);
	free(res);
	free(returnColumnSizes); 
	return 0;
}

注意

本题不好想,着重理解一下代码,算法思想。