Leet_code---15三数之和---C语言版

题目描述:

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

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

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

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

题干分析:

  本题对返回值的要求低,限制少,在此基础上可以有很多种展开思路,基于性能和常用考虑,本次选取快速排序后依次检验的方式;//本系列尽可能每道题采用不一样的方法,在本题中也可采取其他方式排序;

思路分析:

    对于只有数字反馈要求的题目我们应该优先考虑先排序后处理,因为排序只会占用我们nlongn的处理时间,但在后续操作中的优势却会逐渐增大,甚至于某些题目离开了排序接近于无解;

   排序后我们可以清楚地认识到三数之和==0这个条件,意味着在数字不全为0的情况下,至少有一个负数的存在,固排序后的情况大概率为:

CASE 1:[-∞,··· (,0,) ···,∞]//0可能存在,也可能不存在;

  同样的a+b+c==0也存在以下三种情况:

CASE 1:a,b,c,互异;

CASE 2:a=b=-c/2 ||-a/2=b=c;

CASE 3:a=b=c=0;

  因为上述情况的存在,导致在排序时我们不可以删除重复项,否则CASE 2,CASE 3,就会被忽略掉,严格来讲我们应该做稳定排序,即使在这里排序稳定与否并没有区别,但能做到更好的时候不应该放低要求;

  快排后基于排序的情况,我们选定从左端开始,从最大的负值开始判定是否存在三元组,及存在多少组,直至我们的指针指向的第一个元素大于0,即当前三元组所有数字大于0,跳出循环;

  这里可以改进一个地方,如果nums[i]==nums[i-1],本次循环可以直接跳过,因为上一次已经找出所有与此值有关的三元组了,重复值无需返回;

具体代码如下:

/**
 * Return an array of arrays of size *returnSize.
 * Note: The returned array must be malloced, assume caller calls free().
 */
void quickSort(int* nums,int first,int end){  
    int temp,l,r;  
    if(first>=end)return;  
    temp=nums[first];  
    l=first;r=end;  
    while(l=temp)r--;  
        if(l0)break;//首元素大于0,跳出for,已经查找到所有符合条件的三元组;  
        if(i>0 && nums[i]==nums[i-1])continue; //与上次判定一致,直接跳过,执行i++; 
        begin=i+1;end=numsSize-1; //固定i后在i+1/尾两处放入指针,开始循环; 
        while(begin0) end--;  
            else begin++;  
        } //while 
    } //for 
    *returnSize=top+1; //top作为计数器,即为需要返回的长度; 
    return res;  
}  



你可能感兴趣的:(Leet_code---15三数之和---C语言版)