From 40d8c875e655a510d908820f2956f8139edb71a0 Mon Sep 17 00:00:00 2001 From: begeekmyfriend Date: Thu, 3 Aug 2017 18:13:59 +0800 Subject: [PATCH] Combination sum Signed-off-by: begeekmyfriend --- 039_combination_sum/Makefile | 2 + 039_combination_sum/combination_sum.c | 102 +++++++++++++++++++++++ 040_combination_sum_ii/Makefile | 2 + 040_combination_sum_ii/combination_sum.c | 91 ++++++++++++++++++++ 4 files changed, 197 insertions(+) create mode 100644 039_combination_sum/Makefile create mode 100644 039_combination_sum/combination_sum.c create mode 100644 040_combination_sum_ii/Makefile create mode 100644 040_combination_sum_ii/combination_sum.c diff --git a/039_combination_sum/Makefile b/039_combination_sum/Makefile new file mode 100644 index 0000000..e5462fa --- /dev/null +++ b/039_combination_sum/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O2 -o test combination_sum.c diff --git a/039_combination_sum/combination_sum.c b/039_combination_sum/combination_sum.c new file mode 100644 index 0000000..2687ff5 --- /dev/null +++ b/039_combination_sum/combination_sum.c @@ -0,0 +1,102 @@ +#include +#include +#include + +static void insert_sort(int *a, int size) +{ + int i, j; + for (i = 1; i < size; i++) { + int tmp = a[i]; + for (j = i - 1; j >= 0 && tmp < a[j]; j--) { + a[j + 1] = a[j]; + } + a[j + 1] = tmp; + } +} + +static void combination_recursive(int *nums, int size, int start, int target, + int *solution, int len, + int **results, int *column_sizes, int *count) +{ + int i; + if (target > 0) { + for (i = start; i < size; i++) { + if (i > 0 && nums[i] == nums[i - 1]) { + continue; + } + /* You may dump the content of the solution here, and you would find + * the order of element represents the number of nested layers, and + * the element at the specific order represents the iteration from + * the start in the current recursive layer. + */ + solution[len++] = nums[i]; + combination_recursive(nums, size, i, target - nums[i], solution, len, results, column_sizes, count); + len--; + } + } else if (target == 0) { + results[*count] = malloc(len * sizeof(int)); + memcpy(results[*count], solution, len * sizeof(int)); + column_sizes[*count] = len; + (*count)++; + } +} + +/** + ** Return an array of arrays of size *returnSize. + ** The sizes of the arrays are returned as *columnSizes array. + ** Note: Both returned array and *columnSizes array must be malloced, assume caller calls free(). + **/ +int** combinationSum(int* candidates, int candidatesSize, int target, int** columnSizes, int* returnSize) { + insert_sort(candidates, candidatesSize); + + int *solution = malloc(target * sizeof(int)); + int **results = malloc(100 * sizeof(int *)); + *columnSizes = malloc(100 * sizeof(int)); + *returnSize = 0; + combination_recursive(candidates, candidatesSize, 0, target, solution, 0, results, *columnSizes, returnSize); + return results; + //for (i = 0; i < candidatesSize; i++) { + // //int *columns = malloc(); + // for (j = 1; candidates[i] * j < target, j++) { + // for (k = i + 1; k < candidatesSize; k++) { + // + // } + // int remain = target - candidates[i] * j; + // if (remain == 0) { + // int *column = malloc(sizeof(int)); + // if (count + 1 >= cap) { + // cap *= 2; + // columnSizes = realloc(columnSizes, cap * sizeof(int *)); + // } + // columnSizes[count++] = column; + // } else { + // k = i + 1; + // } + // } + //} +} + +int main(int argc, char **argv) +{ + if (argc <= 2) { + fprintf(stderr, "Usage: ./test target array...\n"); + exit(-1); + } + + int i, j, count = 0; + int target = atoi(argv[1]); + int *nums = malloc((argc - 2) * sizeof(int)); + for (i = 0; i < argc - 2; i++) { + nums[i] = atoi(argv[i + 2]); + } + + int *sizes; + int **lists = combinationSum(nums, argc - 2, target, &sizes, &count); + for (i = 0; i < count; i++) { + for (j = 0; j < sizes[i]; j++) { + printf("%d ", lists[i][j]); + } + printf("\n"); + } + return 0; +} diff --git a/040_combination_sum_ii/Makefile b/040_combination_sum_ii/Makefile new file mode 100644 index 0000000..e5462fa --- /dev/null +++ b/040_combination_sum_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O2 -o test combination_sum.c diff --git a/040_combination_sum_ii/combination_sum.c b/040_combination_sum_ii/combination_sum.c new file mode 100644 index 0000000..52f3083 --- /dev/null +++ b/040_combination_sum_ii/combination_sum.c @@ -0,0 +1,91 @@ +#include +#include +#include +#include + +static bool exist(int **results, int count, int *solution, int len) +{ + int i; + for (i = 0; i < count; i++) { + if (!memcmp(results[i], solution, len * sizeof(int))) { + return true; + } + } + return false; +} + +static void insert_sort(int *a, int size) +{ + int i, j; + for (i = 1; i < size; i++) { + int tmp = a[i]; + for (j = i - 1; j >= 0 && tmp < a[j]; j--) { + a[j + 1] = a[j]; + } + a[j + 1] = tmp; + } +} + +static void combination_recursive(int *nums, int size, int start, int target, + int *solution, int len, + int **results, int *column_sizes, int *count) +{ + int i; + if (target > 0) { + for (i = start; i < size; i++) { + /* You may dump the content of the solution here, and you would find + * the order of element represents the number of nested layers, and + * the element at the specific order represents the iteration from + * the start in the current recursive layer. + */ + solution[len++] = nums[i]; + combination_recursive(nums, size, i + 1, target - nums[i], solution, + len, results, column_sizes, count); + len--; + } + } else if (target == 0) { + if (!exist(results, *count, solution, len)) { + results[*count] = malloc(len * sizeof(int)); + memcpy(results[*count], solution, len * sizeof(int)); + column_sizes[*count] = len; + (*count)++; + } + } +} + +/** + ** Return an array of arrays of size *returnSize. + ** The sizes of the arrays are returned as *columnSizes array. + ** Note: Both returned array and *columnSizes array must be malloced, assume caller calls free(). + **/ +static int** combinationSum(int* candidates, int candidatesSize, int target, int** columnSizes, int* returnSize) +{ + insert_sort(candidates, candidatesSize); + + int *solution = malloc(target * sizeof(int)); + int **results = malloc(100 * sizeof(int *)); + *columnSizes = malloc(100 * sizeof(int)); + *returnSize = 0; + combination_recursive(candidates, candidatesSize, 0, target, solution, 0, results, *columnSizes, returnSize); + return results; +} + +int main(int argc, char **argv) +{ + int i, j, count = 0; + int target = atoi(argv[1]); + int *nums = malloc((argc - 2) * sizeof(int)); + for (i = 0; i < argc - 2; i++) { + nums[i] = atoi(argv[i + 2]); + } + + int *sizes; + int **lists = combinationSum(nums, argc - 2, target, &sizes, &count); + for (i = 0; i < count; i++) { + for (j = 0; j < sizes[i]; j++) { + printf("%d ", lists[i][j]); + } + printf("\n"); + } + return 0; +}