代码实现:
方法一:排序 + 回溯——超时
有错误
/** * Return an array of arrays of size *returnSize. * The sizes of the arrays are returned as *returnColumnSizes array. * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free(). */ void insert(int *nums, int numsSize, int ind1, int ind2) { if (nums == NULL || ind1 < 0 || ind2 > numsSize - 1 || ind1 >= ind2) { return; } int i, value = nums[ind2]; for (i = ind2; i > ind1; i--) { nums[i] = nums[i - 1]; } nums[i] = value; } int binary_search(int *nums, int numsSize, int key) { int l = 0, r = numsSize - 1, mid; while (l <= r) { mid = (l + r) / 2; if (nums[mid] == key) { return mid; } if (nums[mid] > key) { r = mid - 1; } else { l = mid + 1; } } return l; } void insert_sort(int *nums, int numsSize) { for (int i = 1; i < numsSize; i++) { if (nums[i - 1] > nums[i]) { insert(nums, i + 1, binary_search(nums, i, nums[i]), i); } } } void dfs(int startind, int sum, int *nums, int numsSize, int **res, int *resSize, int *path, int *pathSize, int *used) { if (*pathSize == 3) { if (sum == 0) { int *ret = malloc(sizeof(int) * 3); for (int i = 0; i < *pathSize; i++) { ret[i] = path[i]; } res[*resSize] = ret; (*resSize)++; } return; } for (int i = startind; i < numsSize; i++) { if (i > 0 && nums[i - 1] == nums[i] && used[i - 1] == 0) { // 去重 continue; } path[(*pathSize)++] = nums[i]; used[i] = 1; dfs(i + 1, sum + nums[i], nums, numsSize, res, resSize, path, pathSize, used); (*pathSize)--; used[i] = 0; } } int **threeSum(int *nums, int numsSize, int *returnSize, int **returnColumnSizes) { // 二分插入排序 insert_sort(nums, numsSize); int **res = malloc(sizeof(int*) * 1000000); // 保存最终结果 int resSize = 0; int *path = malloc(sizeof(int) * 3); // 记录每组数据 int pathSize = 0; int *used = malloc(sizeof(int) * numsSize); // 标记,用于去重 memset(used, 0, sizeof(used)); // 0:没有使用过, 1:使用过 dfs(0, 0, nums, numsSize, res, &resSize, path, &pathSize, used); *returnSize = resSize; *returnColumnSizes = malloc(sizeof(int) * resSize); for (int i = 0; i < resSize; i++) { (*returnColumnSizes)[i] = 3; } return res; }
方法二:排序 + 双指针
/** * Return an array of arrays of size *returnSize. * The sizes of the arrays are returned as *returnColumnSizes array. * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free(). */ void insert(int *nums, int numsSize, int ind1, int ind2) { if (nums == NULL || ind1 < 0 || ind2 > numsSize - 1 || ind1 >= ind2) { return; } int i, value = nums[ind2]; for (i = ind2; i > ind1; i--) { nums[i] = nums[i - 1]; } nums[i] = value; } int binary_search(int *nums, int numsSize, int key) { int l = 0, r = numsSize - 1, mid; while (l <= r) { mid = (l + r) / 2; if (nums[mid] == key) { return mid; } if (nums[mid] > key) { r = mid - 1; } else { l = mid + 1; } } return l; } void insert_sort(int *nums, int numsSize) { for (int i = 1; i < numsSize; i++) { if (nums[i - 1] > nums[i]) { insert(nums, i + 1, binary_search(nums, i, nums[i]), i); } } } int **threeSum(int *nums, int numsSize, int *returnSize, int **returnColumnSizes) { // 二分插入排序 insert_sort(nums, numsSize); int **res = malloc(sizeof(int*) * 1000000); int resSize = 0; for (int i = 0; i < numsSize; i++) { if (nums[i] > 0) { // 优化 break; } if (i > 0 && nums[i] == nums[i - 1]) { // 去重 continue; } int l = i + 1, r = numsSize - 1; while (l < r) { int sum = nums[i] + nums[l] + nums[r]; if (sum == 0) { res[resSize] = malloc(sizeof(int) * 3); res[resSize][0] = nums[i]; res[resSize][1] = nums[l]; res[resSize][2] = nums[r]; resSize++; while (l < r && nums[l] == nums[l + 1]) { // 优化 l++; } while (l < r && nums[r] == nums[r - 1]) { // 优化 r--; } l++, r--; } else if (sum > 0) { r--; while (l < r && nums[r] == nums[r + 1]) { // 优化 r--; } } else { l++; while (l < r && nums[l] == nums[l - 1]) { // 优化 l++; } } } } *returnSize = resSize; *returnColumnSizes = malloc(sizeof(int) * resSize); for (int i = 0; i < resSize; i++) { (*returnColumnSizes)[i] = 3; } return res; }