diff --git a/131_palindrome_patitioning/palindrome_partition.c b/131_palindrome_patitioning/palindrome_partition.c index 14362ad..25f2e88 100644 --- a/131_palindrome_patitioning/palindrome_partition.c +++ b/131_palindrome_patitioning/palindrome_partition.c @@ -19,22 +19,12 @@ static void collect(char *s, int len, int low, int high, struct palindrome *resu } } -static void show(struct palindrome **stack, int size) -{ - int i; - for (i = 0; i < size; i++) { - printf("%d %d %d\n", i, stack[i]->low, stack[i]->high); - } -} - static void recursive(struct palindrome *pal_set, int num, int start, char *s, int len, struct palindrome **stack, int size, char ***results, int *col_sizes, int *count) { int i; - int begin = 0; - int end = size == 0 ? 0 : size - 1; - if (size > 0 && stack[begin]->low == 0 && stack[end]->high == len - 1) { + if (size > 0 && stack[size - 1]->high == len - 1) { col_sizes[*count] = size; results[*count] = malloc(size * sizeof(char *)); for (i = 0; i < size; i++) { @@ -47,7 +37,8 @@ static void recursive(struct palindrome *pal_set, int num, int start, (*count)++; } else { for (i = start; i < num; i++) { - if (size == 0 || stack[size - 1]->high + 1 == pal_set[i].low) { + if ((size == 0 && pal_set[i].low == 0) || + (size > 0 && stack[size - 1]->high + 1 == pal_set[i].low)) { stack[size] = &pal_set[i]; recursive(pal_set, num, i + 1, s, len, stack, size + 1, results, col_sizes, count); } @@ -60,14 +51,14 @@ static void recursive(struct palindrome *pal_set, int num, int start, ** The sizes of the arrays are returned as *columnSizes array. ** Note: Both returned array and *columnSizes array must be malloced, assume caller calls free(). **/ -char*** partition(char* s, int** columnSizes, int* returnSize) { +char ***partition(char* s, int** columnSizes, int* returnSize) { int len = strlen(s); if (len == 0) { *returnSize = 0; return NULL; } - int i, cap = 1000, count = 0; + int i, cap = 800, count = 0; struct palindrome *pal_set = malloc(cap * sizeof(*pal_set)); for (i = 0; i < len; i++) { collect(s, len, i, i, pal_set, &count); diff --git a/132_palindrome_patitioning_ii/Makefile b/132_palindrome_patitioning_ii/Makefile new file mode 100644 index 0000000..3179327 --- /dev/null +++ b/132_palindrome_patitioning_ii/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O2 -o test palindrome_partition.c diff --git a/132_palindrome_patitioning_ii/palindrome_partition.c b/132_palindrome_patitioning_ii/palindrome_partition.c new file mode 100644 index 0000000..35170ac --- /dev/null +++ b/132_palindrome_patitioning_ii/palindrome_partition.c @@ -0,0 +1,89 @@ +#include +#include +#include +#include + +#if 0 +int minCut(char *s) +{ + int len = strlen(s); + if (len <= 1) { + return 0; + } + + int i, j; + bool **isPal = malloc(len * sizeof(bool *)); + for (i = 0; i < len; i++) { + isPal[i] = malloc(len); + memset(isPal[i], false, len); + } + + for (i = len - 1; i >= 0; i--) { + for(j = i; j < len; j++) { + if ((i + 1 > j - 1 || isPal[i + 1][j - 1]) && s[i] == s[j]) { + isPal[i][j] = true; + } + } + } + + int *cuts = malloc((len + 1) * sizeof(int)); + for (i = 0; i <= len; i++) { + cuts[i] = i - 1; + } + + for (i = 1; i <= len; i++) { + for (j = i - 1; j >= 0; j--) { + if (isPal[j][i - 1]) { + if (cuts[j] + 1 < cuts[i]) { + cuts[i] = cuts[j] + 1; + } + } + } + } + + return cuts[len]; +} +#endif + +static int minCut(char* s) +{ + int len = strlen(s); + if (len <= 1) { + return 0; + } + + int i, j; + int *cuts = malloc((len + 1) * sizeof(int)); + for (i = 0; i <= len; i++) { + cuts[i] = i - 1; + } + + for (i = 0; i < len; i++) { + /* odd length palindrome */ + for (j = 0; i - j >= 0 && i + j < len && s[i - j] == s[i + j]; j++) { + if (cuts[i - j] + 1 < cuts[i + j + 1]) { + cuts[i + j + 1] = cuts[i - j] + 1; + } + } + + /* even length palindrome */ + for (j = 1; i - j + 1 >= 0 && i + j < len && s[i - j + 1] == s[i + j]; j++) { + if (cuts[i - j + 1] + 1 < cuts[i + j + 1]) { + cuts[i + j + 1] = cuts[i - j + 1] + 1; + } + } + } + + return cuts[len]; +} + +int main(int argc, char **argv) +{ + if (argc != 2) { + fprintf(stderr, "Usage: ./test string\n"); + exit(-1); + } + + printf("%d\n", minCut(argv[1])); + return 0; +}