Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.
Note:
For example, given array S = {1 0 -1 0 -2 2}, and target = 0. A solution set is: (-1, 0, 0, 1) (-2, -1, 1, 2) (-2, 0, 0, 2)给一个数组,nums, 有numsSize个数,问其中有多少种4个数字的subset之和等于target。
/** * Return an array of arrays of size *returnSize. * Note: The returned array must be malloced, assume caller calls free(). */ int** fourSum(int* nums, int numsSize, int target, int* returnSize)
题目的tricks:
1) 数组元素个数可能小于4
2) 相同数字组成的set需要去重,例如: nums = [0, 0, 0, 0, 0, 0, 0],target=0, 仅有一组解,[0, 0, 0, 0]。
3) 由于结果的个数不可确定,指针数组的初始化的大小不确定,在最后需要mencpy。所以在最开始,初始化的时候,malloc了10000个sizeof(int*).
解题思路:
1)首先,将nums从小到大排序
2)取四个数,a, b, c, d 遍历一组4个数的下标,用暴力循环确定a -> 0 ~ numsSize - 4, b -> a ~ numsSize
for (a = 0; a <= numsSize - 4; ){ for (b = a + 1; b <= numsSize - 3; ){ .............. while (nums[b] == nums[b + 1] && b <= numsSize - 3){ b++; } b++; } while (nums[a] == nums[a + 1] && a <= numsSize - 4){ a++; } a++; }3) c = b + 1, d = numsSize - 1
指针数组的初始化和调用:
变量:int **point
初始化:point = (int**)malloc(sizeof(int*) * NUM)
赋值:int *block = (int*)malloc(sizeof(int*) * BLOCK_NUM);
block[0] = 3; block[1] = 4; block[2] = 5;
point[i] = block;
调用:point[0][0] = 3;
#include <cstdio> #include <cstdlib> #include <ctime> #include <cstring> #define MAX_NUM 10000 /** * Return an array of arrays of size *returnSize. * Note: The returned array must be malloced, assume caller calls free(). */ int** fourSum(int* nums, int numsSize, int target, int* returnSize) { if (numsSize < 4){ return NULL; } int a, b, c, d; int **result; int **tmp_result; int *tmp_loc; int i, j; int sum, tmp; *returnSize = 0; result = (int **)malloc(sizeof(int *) * (MAX_NUM)); for (i = 0; i < numsSize; i++){ for (j = 0; j < numsSize - i - 1; j++){ if (nums[j] > nums[j + 1]){ tmp = nums[j]; nums[j] = nums[j + 1]; nums[j + 1] = tmp; } } } for (a = 0; a <= numsSize - 4; ){ for (b = a + 1; b <= numsSize - 3; ){ for (c = b + 1, d = numsSize - 1; c < d; ){ sum = nums[a] + nums[b] + nums[c] + nums[d]; if (sum < target){ while (nums[c] == nums[c + 1] && c < d){ c++; } c++; } else if (sum > target){ while (nums[d] == nums[d - 1] && c < d){ d--; } d--; } else if (sum == target){ tmp_loc = (int*) malloc(sizeof(int) * 4); tmp_loc[0] = nums[a]; tmp_loc[1] = nums[b]; tmp_loc[2] = nums[c]; tmp_loc[3] = nums[d]; result[*returnSize] = tmp_loc; *returnSize = *returnSize + 1; while (nums[c] == nums[c + 1] && c < d){ c++; } c++; while (nums[d] == nums[d - 1] && c < d){ d--; } d--; } } while (nums[b] == nums[b + 1] && b <= numsSize - 3){ b++; } b++; } while (nums[a] == nums[a + 1] && a <= numsSize - 4){ a++; } a++; } tmp_result = (int **)malloc(sizeof(int *) * (*returnSize)); memcpy(tmp_result, result, *returnSize * sizeof(int*)); free(result); return tmp_result; } int main(void){ int arr[] = {1,-2,-5,-4,-3,3,3,5}; int target = -11; int size = 8; int i, j; int returnSize; int **result; result = fourSum(arr, size, target, &returnSize); printf("%d\n", returnSize); for (i = 0; i < returnSize; i++){ for (j = 0; j < 4; j++){ printf("%d, ", result[i][j]); } printf("\n"); } return 0; }