diff --git a/056_merge_intervals/Makefile b/056_merge_intervals/Makefile new file mode 100644 index 0000000..9b568bc --- /dev/null +++ b/056_merge_intervals/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O2 -o test merge_intervals.c diff --git a/056_merge_intervals/merge_intervals.c b/056_merge_intervals/merge_intervals.c new file mode 100644 index 0000000..a07096d --- /dev/null +++ b/056_merge_intervals/merge_intervals.c @@ -0,0 +1,151 @@ +#include +#include +#include + +struct Interval { + int start; + int end; +}; + +static int binary_search(int *nums, int size, int target) +{ + int low = -1; + int high = size; + while (low + 1 < high) { + int mid = low + (high - low) / 2; + if (target > nums[mid]) { + low = mid; + } else { + high = mid; + } + } + if (high == size || nums[high] != target) { + return -high - 1; + } else { + return high; + } +} + +/** + ** Return an array of size *returnSize. + ** Note: The returned array must be malloced, assume caller calls free(). + **/ +static struct Interval* insert(struct Interval* intervals, int intervalsSize, struct Interval newInterval, int* returnSize) +{ + struct Interval *p; + if (intervalsSize == 0) { + p = malloc(sizeof(*p)); + p->start = newInterval.start; + p->end = newInterval.end; + *returnSize = 1; + return p; + } + + int i, count; + int *nums = malloc(2 * intervalsSize * sizeof(int)); + for (i = 0; i < intervalsSize; i++) { + nums[i * 2] = intervals[i].start; + nums[i * 2 + 1] = intervals[i].end; + } + + int start0 = binary_search(nums, 2 * intervalsSize, newInterval.start); + int end0 = binary_search(nums, 2 * intervalsSize, newInterval.end); + + int start1 = -1, end1 = -1; + int merge_start= -1, merge_end = -1; + if (start0 >= 0) { + merge_start = start0 / 2; + } else { + start1 = -start0 - 1; + merge_start = start1 / 2; + } + + if (end0 >= 0) { + merge_end = end0 / 2; + } else { + end1 = -end0 - 1; + if (end1 % 2 == 0) { + merge_end = end1 / 2 > 0 ? end1 / 2 - 1 : 0; + } else { + merge_end = end1 / 2; + } + } + + if (merge_start == merge_end) { + if (start0 < 0 && end0 < 0 && start1 == end1 && start1 % 2 == 0) { + count = intervalsSize + 1; + p = malloc(count * sizeof(*p)); + memcpy(p, intervals, merge_start * sizeof(*p)); + p[merge_start] = newInterval; + memcpy(p + merge_start + 1, intervals + merge_start, (intervalsSize - merge_start) * sizeof(*p)); + } else { + count = intervalsSize; + p = malloc(count * sizeof(*p)); + memcpy(p, intervals, count * sizeof(*p)); + if (start0 < 0 && start1 % 2 == 0) { + p[merge_start].start = newInterval.start; + } + if (end0 < 0 && end1 % 2 == 0) { + p[merge_end].end = newInterval.end; + } + } + } else { + count = intervalsSize - (merge_end - merge_start); + p = malloc(count * sizeof(*p)); + memcpy(p, intervals, merge_start * sizeof(*p)); + memcpy(p + merge_start, intervals + merge_end, (intervalsSize - merge_end) * sizeof(*p)); + if (start0 < 0 && start1 % 2 == 0) { + p[merge_start].start = newInterval.start; + } else { + p[merge_start].start = intervals[merge_start].start; + } + if (end0 < 0 && end1 % 2 == 0) { + p[merge_start].end = newInterval.end; + } else { + p[merge_start].end = intervals[merge_end].end; + } + } + + free(nums); + free(intervals); + *returnSize = count; + return p; +} + +/** + * * Return an array of size *returnSize. + * * Note: The returned array must be malloced, assume caller calls free(). + * */ +struct Interval* merge(struct Interval* intervals, int intervalsSize, int* returnSize) { + int i, count = 0; + struct Interval *p = NULL; + for (i = 0; i < intervalsSize; i++) { + p = insert(p, count, intervals[i], &count); + } + *returnSize = count; + return p; +} + +int main(int argc, char **argv) +{ + if (argc < 1|| argc % 2 == 0) { + fprintf(stderr, "Usage: ./test s0 e0 s1 e1..."); + exit(-1); + } + + int i, count = 0; + struct Interval *intervals = malloc((argc - 1) / 2 * sizeof(struct Interval)); + struct Interval *p = intervals; + for (i = 1; i < argc; i += 2) { + p->start = atoi(argv[i]); + p->end = atoi(argv[i + 1]); + p++; + } + + struct Interval *q = merge(intervals, (argc - 1) / 2, &count); + for (i = 0; i < count; i++) { + printf("[%d, %d]\n", q->start, q->end); + q++; + } + return 0; +} diff --git a/057_insert_interval/Makefile b/057_insert_interval/Makefile new file mode 100644 index 0000000..bc9dd24 --- /dev/null +++ b/057_insert_interval/Makefile @@ -0,0 +1,2 @@ +all: + gcc -O2 -o test insert_interval.c diff --git a/057_insert_interval/insert_interval.c b/057_insert_interval/insert_interval.c new file mode 100644 index 0000000..fd29352 --- /dev/null +++ b/057_insert_interval/insert_interval.c @@ -0,0 +1,139 @@ +#include +#include +#include + +struct Interval { + int start; + int end; +}; + +static int binary_search(int *nums, int size, int target) +{ + int low = -1; + int high = size; + while (low + 1 < high) { + int mid = low + (high - low) / 2; + if (target > nums[mid]) { + low = mid; + } else { + high = mid; + } + } + if (high == size || nums[high] != target) { + return -high - 1; + } else { + return high; + } +} + +/** + ** Return an array of size *returnSize. + ** Note: The returned array must be malloced, assume caller calls free(). + **/ +static struct Interval* insert(struct Interval* intervals, int intervalsSize, struct Interval newInterval, int* returnSize) { + struct Interval *p; + if (intervalsSize == 0) { + p = malloc(sizeof(*p)); + p->start = newInterval.start; + p->end = newInterval.end; + *returnSize = 1; + return p; + } + + int i, count; + int *nums = malloc(2 * intervalsSize * sizeof(int)); + for (i = 0; i < intervalsSize; i++) { + nums[i * 2] = intervals[i].start; + nums[i * 2 + 1] = intervals[i].end; + } + + int start0 = binary_search(nums, 2 * intervalsSize, newInterval.start); + int end0 = binary_search(nums, 2 * intervalsSize, newInterval.end); + + int start1 = -1, end1 = -1; + int merge_start= -1, merge_end = -1; + if (start0 >= 0) { + merge_start = start0 / 2; + } else { + start1 = -start0 - 1; + merge_start = start1 / 2; + } + + if (end0 >= 0) { + merge_end = end0 / 2; + } else { + end1 = -end0 - 1; + if (end1 % 2 == 0) { + merge_end = end1 / 2 > 0 ? end1 / 2 - 1 : 0; + } else { + merge_end = end1 / 2; + } + } + + if (merge_start == merge_end) { + if (start0 < 0 && end0 < 0 && start1 == end1 && start1 % 2 == 0) { + count = intervalsSize + 1; + p = malloc(count * sizeof(*p)); + memcpy(p, intervals, merge_start * sizeof(*p)); + p[merge_start] = newInterval; + memcpy(p + merge_start + 1, intervals + merge_start, (intervalsSize - merge_start) * sizeof(*p)); + } else { + count = intervalsSize; + p = malloc(count * sizeof(*p)); + memcpy(p, intervals, count * sizeof(*p)); + if (start0 < 0 && start1 % 2 == 0) { + p[merge_start].start = newInterval.start; + } + if (end0 < 0 && end1 % 2 == 0) { + p[merge_end].end = newInterval.end; + } + } + } else { + count = intervalsSize - (merge_end - merge_start); + p = malloc(count * sizeof(*p)); + memcpy(p, intervals, merge_start * sizeof(*p)); + memcpy(p + merge_start, intervals + merge_end, (intervalsSize - merge_end) * sizeof(*p)); + if (start0 < 0 && start1 % 2 == 0) { + p[merge_start].start = newInterval.start; + } else { + p[merge_start].start = intervals[merge_start].start; + } + if (end0 < 0 && end1 % 2 == 0) { + p[merge_start].end = newInterval.end; + } else { + p[merge_start].end = intervals[merge_end].end; + } + } + + free(nums); + *returnSize = count; + return p; +} + +int main(int argc, char **argv) +{ + if (argc < 3 || argc % 2 == 0) { + fprintf(stderr, "Usage: ./test new_s new_e s0 e0 s1 e1..."); + exit(-1); + } + + struct Interval new_interv; + new_interv.start = atoi(argv[1]); + new_interv.end = atoi(argv[2]); + + int i, count = 0; + struct Interval *intervals = malloc((argc - 3) / 2 * sizeof(struct Interval)); + struct Interval *p = intervals; + for (i = 3; i < argc; i += 2) { + p->start = atoi(argv[i]); + p->end = atoi(argv[i + 1]); + p++; + } + + struct Interval *q = insert(intervals, (argc - 3) / 2, new_interv, &count); + for (i = 0; i < count; i++) { + printf("[%d, %d]\n", q->start, q->end); + q++; + } + return 0; +}