学渣带你刷Leetcode0015. 三数之和

题目描述

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。

 

示例:

给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/3sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

白话题目:

一个数组,找到里面三个数的和为0就行,都得找出来,之后不能有重复的。

算法:

(1)快排输入数组,调用系统的Qsort函数,是根据二分法写的,其时间复杂度为n*log(n)

void qsort(void* base,size_t num,size_t width,int(__cdecl*compare)(const void*,const void*));

 参数: 1 待排序数组,排序之后的结果仍放在这个数组中
      2 数组中待排序元素数量
        3 各元素的占用空间大小(单位为字节)
             4 指向函数的指针,用于确定排序的顺序(需要用户自定义一个比较函数)

讲普通话, qsort(nums, numsSize, sizeof(int), comp);//用自带的排序

(2)结果长啥样子

6个数,取三个数,如何都取出来形成结果是不是得很多,C_{6}^{3}够用了吧,不动脑筋的就来个numsSize*numsSize,这里面得去重,不符合之类的处理。

还有leetcode这里一个特殊参数的处理,也是加强了对于二维指针的理解,详见代码详细讲解视频

(3)优化提速

暴力肯定超时,就用双指针,以第一个点为核心,之后移动L=i+1,R=numsSize-1;

详细解释关注 B站  【C语言全代码】学渣带你刷Leetcode 不走丢 https://www.bilibili.com/video/BV1C7411y7gB

C语言完全代码

#include <stdio.h>
#include <stdlib.h>
/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */

int comp(const void *_a,const void *_b)  //const void *a这是定义了一个指针a,a可以指向任意类型的值,但它指向的值必须是常量
{
    int* a = (int*)_a;    //  强制转换成整型指针
    int* b = (int*)_b;
    return *a - *b;   //默认升序排列(从小到大),如果想降序排列返回*b-*a即可
}

//int** threeSum(int* nums, int numsSize, int* returnSize)
//{
int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes)
{
    *returnSize = 0;    //*p 取值
    //当输入元素不足3个
    if(numsSize < 3)
    {
        return 0;
    }

    //初始化结果数组为numsSize行*numsSize列的
    int** returnArray = (int**)malloc(sizeof(int*) * (numsSize)*(numsSize));  //Cn3就够了

    // *returnColumnSizes = (int*)malloc(sizeof(int) * (numsSize)*(numsSize));
    *returnColumnSizes = (int*)malloc(sizeof(int) * (numsSize)*(numsSize));      //returnColumnSizes【】【】    returnColumnSizes[]
     //*returnColumnSizes =  (int*)calloc(sizeof(int), *returnSize);  //层序的最后要是这么写就没有事
    // for (int i = 0; i < *returnSize; i++) {
    //     (*returnColumnSizes)[i] = 3;
    // }

    qsort(nums, numsSize, sizeof(int), comp);//用自带的排序
    int i;
    for( i=0; i < numsSize; i++)
    {
        //若排序后的数组首元素大于0 ,则肯定不存在三元组
        if(nums[0] > 0)
        {
            return NULL;
        }


        if(i > 0 && nums[i] == nums[i-1])   //之前的找过了,再找会一样,去重
        {
            continue;
        }

        int L = i+1, R = numsSize-1;
        while(L < R)
        {
            if(nums[i] + nums[L] + nums[R] == 0)
            {
                // 每次找到一组,二级指针就分配三个空间
                returnArray[*returnSize] = (int*)malloc(sizeof(int) * 3);    //从0行开始
                (*returnColumnSizes)[*returnSize] = 3; //

                returnArray[*returnSize][0] = nums[i];
                returnArray[*returnSize][1] = nums[L];
                returnArray[*returnSize][2] = nums[R];
                (*returnSize)++;
                //去重2:左指针移动到最后1个相同元素
                while(L < R && (nums[L] == nums[L+1]))
                {
                    L++;
                }
                //去重3:右指针移动到最后1个相同元素
                while(L < R && (nums[R] == nums[R-1]))
                {
                    R--;
                }
                //双指针例行移动1位
                L++;
                R--;
            }
            else if(nums[i] + nums[L] + nums[R] < 0)
            {
                //调大
                L++;
            }
            else
            {
                R--;
            }
        }
    }

    return returnArray;
}

int main()
{   printf("测试数据的个数  6\n");
    int numsSize;
    scanf("%d",&numsSize);
    int nums[numsSize];
    int i,j;
    printf("测试数据 -1, 0, 1, 2, -1, -4 \n");
    for(i=0; i<numsSize; i++)
    {
        scanf("%d",&nums[i]);
    }

    int  **returnColumnSizes =(int**)malloc(sizeof(int*)*numsSize);
    int returnSize=0;

    //输出
    int** resultArray = threeSum( nums,  numsSize,  &returnSize,returnColumnSizes);

    printf("%d\n",returnSize);

    for(i=0; i<returnSize; i++)
    {
        for ( j = 0; j < (*returnColumnSizes)[i]; j ++)
        {
            printf("%d ",resultArray[i][j]) ;
        }
        printf("\n");
    }



    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值