[leetcode]15. 三数之和

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

例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

2.代码:

/**
 * Return an array of arrays of size *returnSize.
 * Note: The returned array must be malloced, assume caller calls free().
 */
 
/*
对于算法跳过i,m,n相同部分:
 0   1   2  3  4  5  6  7  8  9
-2, -2, -2, 0, 0, 0, 1, 1, 3, 4
1.对于i跳过相同元素:
必须的,不然会出现重复序列
2.对于m,n跳过相同元素:
若要相同序列最后一个:
 0   1   2  3  4  5  6  7  8  9
-2, -2, -2, 0, 0, 0, 1, 1, 3, 4
i,m,n:没有0,6,7和3,4,5,只有0,1,9
因为i=0,m如果去最后一个1,直接到7了,n就没法在m<n的条件下到7,就算能到7,那m和n能去一个地方情况就复杂了;
同理i=3,m直接去5,n没法去;
所以m,n选择各自方向上第一个,即
m==m-1=>m++
n==n+1=>n--
*并且这部分要放在else里:
 0   1   2  3  4  5  6  7  8  9
-2, -2, -2, 0, 0, 0, 1, 1, 3, 4
不然i,m,n为3,4,5的情况就没了
i,m,n变化过程:3,4,,9->3,4,8->3,5,8(跳相同m,n)...,完美跳过3,4,5
*/

//升序
int compare(const void* a, const void* b) {
    return (*(int*)a)-(*(int*)b);
}

int** threeSum(int* nums, int numsSize, int* returnSize) {
    *returnSize=0;
    int** r=malloc(sizeof(int*)*numsSize*numsSize);
    qsort(nums,numsSize,sizeof(int),compare);
    for(int i=0;i<numsSize-2;i++){        
        int m=i+1;
        int n=numsSize-1;
        //对于i,重复的只看最后一个,不然的话会重复序列,i>0,防止溢出        
        if(i>0&&nums[i]==nums[i-1])
            continue;
         //因为是升序,若nums[i]>0,则后面也>0,不用看了
        if(nums[i]>0)  
            return r;                
        while(m<n){                      
            if(nums[m]+nums[n]>-nums[i])
                n--;
            else if(nums[m]+nums[n]<-nums[i])
                m++;
            else{           
                int *s=(int *)malloc(sizeof(int )*3);            
                s[0]=nums[i];
                s[1]=nums[m++];
                s[2]=nums[n--];
                r[*returnSize]=s;
                (*returnSize)++;                    
                while(m<numsSize-1&&nums[m]==nums[m-1])
                    m++;
                //放到后面就不会有溢出问题
                while(n>i+1&&nums[n]==nums[n+1])                
                    n--;
            }          
        }
    }
    return r;
}

3.知识点:

二维数组+找出两数之和

猜你喜欢

转载自blog.csdn.net/MJ_Lee/article/details/88808121