zoukankan      html  css  js  c++  java
  • leetcode复盘:15.三数之和

    leetcode复盘:15.三数之和

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

    一、个人小结:

    (1)排序:由于不能包含重复的三元组,需要先对数组进行排序;排序时可以使用C中自带的qsort方法,排序常用代码如下:

     int cmp(const void *a, const void *b) 
     {
    	//从小到大排序
         return *(int*)a - *(int*)b;
     }
    
     //nums为数组名,numsize为数组大小,cmp为比较函数
     //高级做法,可以比较结构体中的数据
     qsort(nums, numsSize, sizeof(int), cmp);
    

    (2)内存申请(二位数组):malloc函数,入参为申请内存大小,赋值前一般强制转化成目标类型,比如一次指针或二次指针。
    一维数组内存申请:

    int *arrOne = (int*)malloc(arrOneSize * sizeof(int));  
    

    注:arrOne为一次指针类型,则malloc自然强制转化成一次指针类型,arrOne为int型指针,每个元素大小为sizeof(int),且共有arrOneSize个元素,所有内存申请大小为(arrOneSize * sizeof(int)),其单位为字节。
    二维数组内存申请:

        int **arrTwo = (int**)malloc(arrTwoSize * sizeof(int *));
    

    注:
    (a)与一位数组内存申请如出一辙,只不过arrTwo为二次指针,即指向指针的指针,即*arrTwo或者arrTwo[0]仍然是一个指针;
    (b)申请完以上内存后,arrTwo指向的一片内存中,一共可以存放arrTwoSize个int型的指针,所以其大小为(arrTwoSize * sizeof(int *)),单位为字节;
    (c)申请完以上内存后,只能存放几个地址,还不能存放用户数据,所有可以针对每个指针,再次申请存放数据的内存:

        int arrTwo[0] = (int *)malloc(arrTwoSize0 * sizeof(int));  
        int arrTwo[1] = (int *)malloc(arrTwoSize1 * sizeof(int));  
        int arrTwo[2] = (int *)malloc(arrTwoSize2 * sizeof(int)); 
        int arrTwo[3] = (int *)malloc(arrTwoSize3 * sizeof(int)); 
    

    (d)arrTwo[0]、arrTwo[1]、arrTwo[2]、arrTwo[3]均为指针,其值存放在第一次为arrTwo申请的内存中,这样的指针一共由arrTwoSize个;而现在arrTwo[0]指向了一片新申请的内存,其中可以存放(arrTwoSize0 * sizeof(int))这么多字节的数据,至此,就完成了二维数组的申请

    二:解题过程

    解题参考 画家王铁男https://leetcode-cn.com/problems/3sum/solution/chun-c-kuai-pai-shuang-zhi-zhen-by-hua-jia-wang-ti/
    (1)先将数组排序;求三数之和,可以先固定一个数,然后求其他两个数;固定当前数后,使用双指针法,一头一尾逐步搜索, 逼近;
    (2)本题中,一个大坑在于对returnColumnSizes的处理,该变量实际上使用个一维指针就可以,偏偏要用个二维指针,其实是在当一维指针用,用于存储每个返回数组的长度,其实冗余,题意中已经明确返回数组长度为3,强行提高题目难度;
    (3)变量去重,是本题的难点,在数组排序后,遍历cur、low、high时,需要考虑重复;去重操作是本题的精髓所在;在确定cur时,需要针对low、high去重;在遍历cur时,需要对cur去重

    /**
     * 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 cmp(const void *a, const void *b) 
     {
         //从小到大
         return *(int*)a - *(int*)b;
     }
    int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
            *returnSize = 0;
        if (numsSize < 3) {
            return NULL;
        }
        qsort(nums, numsSize, sizeof(int), cmp);
        //申请内存
        int **threeNum = (int**)malloc(6 * numsSize * sizeof(int *));
        //实际上使用个一维指针就可以,偏偏要用个二维指针,其实是在当一维指针用
        *returnColumnSizes = (int*)malloc(6 * numsSize * sizeof(int));
        int cur = 0;
        int low = cur + 1;
        int high = numsSize - 1;
        while ((nums[cur] <= 0) && (cur < numsSize - 2)) {
            low = cur + 1;
            high = numsSize - 1;
            while (low < high) {
                if (nums[cur] + nums[low] + nums[high] == 0) {
                    threeNum[*returnSize] = (int*)malloc(3*sizeof(int));
                    //(*returnColumnSizes)[*returnSize] = 3;
                    returnColumnSizes[0][*returnSize] = 3;
                    threeNum[*returnSize][0] = nums[cur];
                    threeNum[*returnSize][1] = nums[low];
                    threeNum[*returnSize][2] = nums[high];
                    (*returnSize)++;
                    //lowhigh 去重
                    while((nums[low] == nums[++low]) && (low < high)){
                    }
                    while((nums[high] == nums[--high]) && (low < high)){
                    }
                } else if (nums[cur] + nums[low] + nums[high] > 0) {
                    high--;
                } else {
                    low++;
                }
            }
            //cur去重
            while((nums[cur] == nums[++cur]) && (cur < numsSize - 2)){
            }
        }
        return threeNum;
    }
    
    

    三、运行结果

  • 相关阅读:
    解决 Mac launchpad 启动台 Gitter 图标无法删除的问题
    React 与 React-Native 使用同一个 meteor 后台
    解决 React-Native mac 运行报错 error Failed to build iOS project. We ran "xcodebuild" command but it exited with error code 65. To debug build logs further, consider building your app with Xcode.app, by ope
    一行命令更新所有 npm 依赖包
    swift学习笔记
    IOS语言总结
    focusSNS学习笔记
    别小看锤子,老罗真的很认真
    windowsphone开发页面跳转到另一个dll中的页面
    【令人振奋】【转】微软潘正磊谈DevOps、Visual Studio 2013新功能、.NET未来
  • 原文地址:https://www.cnblogs.com/HZL2017/p/13252878.html
Copyright © 2011-2022 走看看