题目15:
代码写的非常复杂和凌乱,需要再进行整理。
Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note:
- Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
- The solution set must not contain duplicate triplets.
For example, given array S = {-1 0 1 2 -1 -4}, A solution set is: (-1, 0, 1) (-1, -1, 2)
#define SCOPE 1000
int** threeSum(int* nums, int numsSize, int* returnSize)
{
int i = 0;
int left = 0; /* 结果左边的数 */
int mid = 0; /* 中间数 */
int right = 0; /* 右边数 */
int** res = NULL; /* 存放结果 */
int res_ptr = 0;
int* temp_res = NULL;
int pos_arr[SCOPE] = {0}; /* 存放正数 */
int neg_arr[SCOPE] = {0}; /* 存放负数 */
int pos_ptr = 0;
int neg_ptr = 0;
int max_pos_ptr = 0;
int max_neg_ptr = 0;
if (numsSize < 3)
{
return NULL;
}
res = (int**)malloc(sizeof(int*) * SCOPE);
/* 遍历数组,将正负数分开,0在正负数组都进行存储
例:假设遍历到1,pos_arr[1]++,遍历到-1,neg_arr[1]++
*/
for (i = 0; i < numsSize; i++)
{
if (nums[i] > 0)
{
pos_arr[nums[i]]++;
}
else
{
if (nums[i] == 0)
{
pos_arr[0]++;
neg_arr[0]++;
}
else
{
neg_arr[nums[i] * (-1)]++;
}
}
}
/* 查找最右边的元素,避免较多循环无用遍历 */
for(i = SCOPE - 1; i >= 0; i--)
{
if (pos_arr[i] > 0)
{
max_pos_ptr = i+1;
break;
}
}
for(i = SCOPE - 1; i >= 0; i--)
{
if (neg_arr[i] > 0)
{
max_neg_ptr = i+1;
break;
}
}
/* 使用两个指针,分别从负数最小和正数最大开始向中间遍历 */
pos_ptr = max_pos_ptr;
while (--pos_ptr >= 0)
{
/* 该正数存在 */
if (pos_arr[pos_ptr] > 0)
{
right = pos_ptr;
}
else
{
continue;
}
neg_ptr = max_neg_ptr;
while (--neg_ptr >= 0)
{
if (neg_arr[neg_ptr] > 0)
{
left = neg_ptr * (-1);
}
else
{
continue;
}
mid = (right + left) * (-1); /* 查找中间数 */
if (mid >= 0)
{
/* 判定条件
1. mid <= pos_ptr,这样mid才位于中间,如果mid > pos_ptr,说明之前已经遍历到,去重不再进行记录
2. mid != right && pos_arr[mid] > 0,位于left和right中间
3. mid == right && pos_arr[mid] > 1 && mid != 0,和right相等,且不等于0
4. mid == 0 && pos_arr[mid] > 2 等于0
*/
if (((mid != right && pos_arr[mid] > 0) || (mid == right && pos_arr[mid] > 1 && mid != 0) || (mid == 0 && pos_arr[mid] > 2)) && (mid <= pos_ptr))
{
temp_res = (int*)malloc(sizeof(int) * 3);
temp_res[0] = left;
temp_res[1] = mid;
temp_res[2] = right;
res[res_ptr++] = temp_res;
(*returnSize)++;
continue;
}
}
else
{
if (((mid != left && neg_arr[(-1)* mid] > 0) || (mid == left && neg_arr[(-1)*mid] > 1)) && (mid * (-1) <= neg_ptr))
{
temp_res = (int*)malloc(sizeof(int) * 3);
temp_res[0] = left;
temp_res[1] = mid;
temp_res[2] = right;
res[res_ptr++] = temp_res;
(*returnSize)++;
continue;
}
}
}
}
free(pos_arr);
free(neg_arr);
return res;
}