题目
给你一个整数数组 nums
,判断是否存在三元组 [nums[i], nums[j], nums[k]]
满足 i != j
、i != k
且 j != k
,同时还满足 nums[i] + nums[j] + nums[k] == 0
。请
你返回所有和为 0
且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4] 输出:[[-1,-1,2],[-1,0,1]] 解释: nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。 nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。 nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。 不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。 注意,输出的顺序和三元组的顺序并不重要。
示例 2:
输入:nums = [0,1,1] 输出:[] 解释:唯一可能的三元组和不为 0 。
示例 3:
输入:nums = [0,0,0] 输出:[[0,0,0]] 解释:唯一可能的三元组和为 0 。
提示:
3 <= nums.length <= 3000
-105 <= nums[i] <= 105
思路
这个题目一拿到手我的想法是把这些数字分成正数和负数,因为如果要得到sum = 0的话,一定要有一个负数,但是这样的话忽略了3个0的情况,因此没有全部通过,而且如果负数正数这么搜索的话,一正一负拿完,如果有重复数字需要重复利用,会导致输出的三元组存在重复的情况,因此需要去重,这个思路的代码是思路1代码。
正常的思路应该是先把数组升序排列,用一个指针遍历数组,再在遍历的时候用双指针从两头向中间逼近,筛出剩余数据。这个思路现成代码很多,就没自己写了。和之前的盛水容器一样了。
分析的时候整理了几个时间复杂度低一些的sort算法:
简单排序算法:
-
冒泡排序 (Bubble Sort)
- 时间复杂度: O(n^2)
- 空间复杂度: O(1)
-
选择排序 (Selection Sort)
- 时间复杂度: O(n^2)
- 空间复杂度: O(1)
-
插入排序 (Insertion Sort)
- 时间复杂度: O(n^2)
- 空间复杂度: O(1)
高效排序算法:
-
快速排序 (Quick Sort)
- 时间复杂度: O(n log n)(最坏情况下是O(n^2),但这种情况不常见)
- 空间复杂度: O(log n)(递归实现需要栈空间)
-
归并排序 (Merge Sort)
- 时间复杂度: O(n log n)
- 空间复杂度: O(n)(需要额外的空间来合并子数组)
-
堆排序 (Heap Sort)
- 时间复杂度: O(n log n)
- 空间复杂度: O(1)(在数组上原地进行堆操作)
其他排序算法:
-
希尔排序 (Shell Sort)
- 时间复杂度: 平均情况下约为O(n log^2 n)至O(n^(3/2)),具体取决于间隔序列的选择
- 空间复杂度: O(1)
-
计数排序 (Counting Sort) - 适用于有限范围整数排序
- 时间复杂度: O(n + k)(k是整数的范围)
- 空间复杂度: O(k)
-
基数排序 (Radix Sort) - 适用于整数排序
- 时间复杂度: O(nk)(k是最大数的位数)
- 空间复杂度: O(n + k)
-
桶排序 (Bucket Sort) - 适用于分布均匀的数据排序
- 时间复杂度: O(n + k)(在最佳情况下,k是桶的数量)
- 空间复杂度: O(n + k)
代码
//思路1代码
#include <stdlib.h>
#include <stdio.h>
_Bool existsInResult(int** result, int returnSize, int a, int b, int c) {
for (int i = 0; i < returnSize; i++) {
if ((result[i][0] == a || result[i][0] == b || result[i][0] == c) &&
(result[i][1] == a || result[i][1] == b || result[i][1] == c) &&
(result[i][2] == a || result[i][2] == b || result[i][2] == c)) {
return true;
}
}
return false;
}
int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) {
*returnColumnSizes = (int*)malloc(numsSize * sizeof(int));
if((*nums == 0) && (*(nums+1) == 0) && (*(nums+2) == 0))
{
int** result = (int**)malloc(1 * sizeof(int*));
result[*returnSize] = (int*)malloc(3 * sizeof(int));
result[*returnSize][0] = 0;
result[*returnSize][1] = 0;
result[*returnSize][2] = 0;
(*returnColumnSizes)[*returnSize] = 3;
(*returnSize) ++;
return result;
}
int* MinusNums = (int*)malloc(numsSize * sizeof(int));
int* Numbers = (int*)malloc(numsSize * sizeof(int));
int *p_Mi = MinusNums;
int *p_Nu = Numbers;
int len_Mi,len_Nu;
int** result = (int**)malloc(numsSize * sizeof(int*));
*returnSize = 0;
for (int i = 0; i < numsSize; i++)
{
if(nums[i] < 0)
{
*p_Mi = nums[i];
p_Mi++;
}
else
{
*p_Nu = nums[i];
p_Nu++;
}
}
len_Mi = p_Mi - MinusNums;
len_Nu = p_Nu - Numbers;
for (p_Mi = MinusNums; p_Mi < MinusNums + len_Mi; p_Mi++)
{
for (p_Nu = Numbers; p_Nu < Numbers + len_Nu; p_Nu++)
{
int sum = *p_Mi + *p_Nu;
if(*returnSize >= numsSize)
{
result = (int**)realloc(result,(sizeof(int*) * (*returnSize) * 2));
*returnColumnSizes=(int*)realloc(*returnColumnSizes,(sizeof(int*) * (*returnSize) * 2));
}
if(sum < 0)
{
for (int i = 0; p_Nu + i < Numbers + len_Nu - 1; i++)
{
if(0 == (sum + *(p_Nu + i)))
{
if (existsInResult(result, *returnSize, *p_Mi, *p_Nu, *(p_Nu + i)))
{
continue;
}
//在这里加入判断是否已经在result中,如果有重复的则执行continue;
result[*returnSize] = (int*)malloc(3 * sizeof(int));
result[*returnSize][0] = *p_Mi;
result[*returnSize][1] = *p_Nu;
result[*returnSize][2] = *(p_Nu + i);
(*returnColumnSizes)[*returnSize] = 3;
(*returnSize) ++;
}
}
}
else
{
for (int i = 0; p_Mi + i < MinusNums + len_Mi - 1; i++)
{
if(0 == (sum + *(p_Mi + i)))
{
if (existsInResult(result, *returnSize, *p_Mi, *p_Nu, *(p_Nu + i)))
{
continue;
}
//在这里加入判断是否已经在result中,如果有重复的则执行continue;
result[*returnSize] = (int*)malloc(3 * sizeof(int));
result[*returnSize][0] = *p_Mi;
result[*returnSize][1] = *p_Nu;
result[*returnSize][2] = *(p_Mi + i);
(*returnColumnSizes)[*returnSize] = 3;
(*returnSize) ++;
}
}
}
}
}
free(MinusNums);
free(Numbers);
return result;
}