11 四数之和

15 阅读1分钟

题目

image.png

思路

和昨天的三数之和很像。排序的代码是一样的。

  1. 先升序排序。

  2. 判断符合条件的四元组。

  3. 去除重复的部分。

着重理解代码即可。

#include<stdio.h>
#include<stdlib.h>
int cmp(const void *a,const void *b){//升序 
	return (*(int *)a- *(int *)b);
}

int **fourSum(int *nums,int numsSize,int target,int *returnSize,int **returnColumnSizes){
	int **res=NULL;//结果集
	int resSize=0;//结果集大小
	qsort(nums,numsSize,sizeof(int),cmp);//升序排列
	
	for(int k=0; k<numsSize; k++){
		if(nums[k]>target && nums[k]>=0)
			break;//排过序了,后面没有符合的
		if(k>0 && nums[k]==nums[k-1])
			continue;
			
		for(int i=k+1; i<numsSize; i++){
			if(nums[k]+nums[i]>target && nums[k]+nums[i]>=0)
				break;
			if(i>k+1 && nums[i]==nums[i-1])
				continue;
				
			int left=i+1;
			int right=numsSize-1;
			while(right>left){
				long sum=(long)nums[k]+nums[i]+nums[left]+nums[right];
				if(sum>target) right--;
				else if(sum<target) left++;
				else{
					resSize++;//找到符合条件的四元组
					res=(int **)realloc(res,resSize*sizeof(int*));
					res[resSize-1]=(int*)malloc(4*sizeof(int)); 
					res[resSize-1][0]=nums[k];
					res[resSize-1][1]=nums[i];
					res[resSize-1][2]=nums[left];
					res[resSize-1][3]=nums[right];
					while(right>left && nums[right]==nums[right-1])
						right--;
					while(right>left && nums[left]==nums[left+1])
						left++;
					
					right--;
					left++; 
				}
			}
		} 
	}
	*returnSize=resSize;
	if(resSize==0){
		*returnColumnSizes=NULL;
		return NULL;
	}
	*returnColumnSizes=(int*)malloc(resSize*sizeof(int));
	for(int i=0; i<resSize; i++)
		(*returnColumnSizes)[i]=4;
	return res; 
}
int main(){
	int nums[]={1,0,-1,0,-2,2};
	int target=0;
	int returnSize;
	int *returnColumnSizes;
	int **res=fourSum(nums,sizeof(nums)/sizeof(nums[0]),target,&returnSize,&returnColumnSizes);
	for(int i=0; i<returnSize; i++){
		for(int j=0; j<returnColumnSizes[i]; j++)
			printf("%d ",res[i][j]);
		printf("\n");
	}
	return 0;
}