三数之和

Posted onlyandonly

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了三数之和相关的知识,希望对你有一定的参考价值。

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

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

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

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

这条题目应该是典型的算法优化题了吧。从方法到循环语句到判断条件,几乎每个地方都要写得完美才不会TLE,虽然我写得可能还是破绽百出。。。

碰到这种题目我都是一股脑地排列组合,也就是穷举。。。后来在循环里加了几个判断条件可以减少很多时间,但还远远不够。。后来从别人那里看到了使用左右指针的思路,不再需要排列组合,终于提交过了。。

这题主要的几个点:

1、不能有重复的三元组。遍历的时候判断一下跟上一个相不相同,相同就跳过。

2、返回数组的内存分配。一开始我算出了所有排列组合的数量,但是我不知道怎么总结出公式(我真是个智障)。。。然后爱咋咋地吧,直接分配了n*n个内存,勉强是提交过了。之后在别人的答案里发现了realloc函数,简直如获至宝啊哈哈哈哈!


                a=(int **)realloc(a,sizeof(int *)*(size+1));

通过这样就可以动态分配内存了,原先内存里的内容也不会被覆盖掉。

3、算法。遍历就不提了,时间复杂度达到O(n^3),真的蠢。。主要是先取一个数,它的相反数就是我们要的target,然后就变成了twoSum,twoSum使用左右指针,每次只要o(n)的时间,最后时间复杂度只有O(n^2)。

 

/**
 * Return an array of arrays of size *returnSize.
 * Note: The returned 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 i,j,k;
    qsort(nums,numsSize,sizeof(int),cmp);
    int **a=0;
    int size=0;
    int size_2=numsSize-2;
    int target,l,r;
    for(i=0;i<size_2;i++)
    {
        if(nums[i]>0)
            break;
        if(i>0&&nums[i]==nums[i-1])
            continue;
        target=0-nums[i];
        l=i+1;r=numsSize-1;
        while(l<r)
        {
            if(nums[l]+nums[r]==target)
            {
                a=(int **)realloc(a,sizeof(int *)*(size+1));
                a[size]=(int *)malloc(sizeof(int)*3);
                a[size][0]=nums[i];
                a[size][1]=nums[l];
                a[size][2]=nums[r];
                size++;
                while(nums[l]==nums[l+1]&&l<r)
                    l++;
                while(nums[r]==nums[r-1]&&l<r)
                    r--;
                l++;
                r--;                   
            }
            else if(nums[l]+nums[r]>target)
                r--;
            else
                l++;
        }
    }
    *returnSize=size;
    return a;
}

 



以上是关于三数之和的主要内容,如果未能解决你的问题,请参考以下文章

最接近的三数之和--力扣

数组练习题:两数之和三数之和四数之和

LeetCode 16. 最接近的三数之和

15. 三数之和

代码随想录算法训练营第7天 | ● 454.四数相加II ● 383. 赎金信 ● 15. 三数之和 ● 18. 四数之和 ● 总结

LeetCode 15. 三数之和