[力扣刷题]15. 三数之和【C语言】

思路详解:

1.将数组从小到大排序

2.首先固定左边第i个数字,转换为两数求和问题

3.用双指针使得left=i+1,right=numSize-1;

4.移动左右指针,满足条件则保存起来,当left==right时,i++并执行第2步骤

难点:去除重复的三元组

1.如果固定的数字判断过后,相同,则跳过。 
	if(i>0&&nums[i]==nums[i-1]){
        continue;
    }
2.同样,双指针指定的数字已经保存后相同,也跳过。
	 left++;
     while(left<right&&nums[left]==nums[left-1]){
         left++;
     }
     right--;
     while(left<right&&nums[right]==nums[right+1]){
         right--;
     }

代码及解析如下:


int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
    * returnSize=0;
    if(numsSize<3){	//如果数字不足3个,返回空
        return NULL;
    }
    int flag=1,temp;
    while(flag){	//冒泡进行数组排序
        flag=0;
        for(int i=0;i<numsSize-1;i++){
            if(nums[i]>nums[i+1]){
                temp=nums[i];
                nums[i]=nums[i+1];
                nums[i+1]=temp;
                flag=1;
            }
        }
    }

    int **res=(int **)malloc(sizeof(int *)*30010);//建立一个保存结果的二维数组
    *returnColumnSizes=(int *)malloc(sizeof(int)*30010);//保存每一行需要存的数字,显然要存3个。
    for(int i=0;i<numsSize-1;i++){ //依次移动左边固定的第i个数字
        int left=i+1,right=numsSize-1;//双指针
        if(i>0&&nums[i]==nums[i-1]){//如果固定的数字重复且判断过,则跳过。注意不可以写成nums[i]==nums[i+1],因为没判断过,可能会跳过left指定的数字。
            continue;
        }
        while(left<right){//双指针循环
            int sum=nums[i]+nums[left]+nums[right];
            if(sum==0){
                res[*returnSize]=(int *)malloc(sizeof(int)*3);
                res[*returnSize][0]=nums[i];
                res[*returnSize][1]=nums[left];
                res[*returnSize][2]=nums[right];
                (*returnColumnSizes)[*returnSize]=3;//要存的3元组
                (*returnSize)++;//行数+1
                left++;
                while(left<right&&nums[left]==nums[left-1]){
                    left++;//去重和上面固定数字去重一样
                }
                right--;
                while(left<right&&nums[right]==nums[right+1]){
                    right--;
                }
            }else if(sum>0){
                right--;
            }else if(sum<0){
                left++;
            }

        }

    }
    return res;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值