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.知识点:
二维数组+找出两数之和