diff --git a/0021_merge_two_sorted_lists/merge_lists.c b/0021_merge_two_sorted_lists/merge_lists.c index 34ecdb0..021a584 100644 --- a/0021_merge_two_sorted_lists/merge_lists.c +++ b/0021_merge_two_sorted_lists/merge_lists.c @@ -9,25 +9,20 @@ struct ListNode { static struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) { struct ListNode dummy; - struct ListNode *prev = &dummy; - dummy.next = l1; + struct ListNode *tail = &dummy; while (l1 != NULL && l2 != NULL) { if (l1->val <= l2->val) { - prev = l1; + tail->next = l1; l1 = l1->next; } else { - struct ListNode *tmp = l2->next; - l2->next = l1; - prev->next = l2; - prev = l2; - l2 = tmp; + tail->next = l2; + l2 = l2->next; } + tail = tail->next; } - if (l2 != NULL) { - prev->next = l2; - } + tail->next = l1 != NULL ? l1 : l2; return dummy.next; } diff --git a/0021_merge_two_sorted_lists/merge_lists.cc b/0021_merge_two_sorted_lists/merge_lists.cc index a5d7a63..58a47f7 100644 --- a/0021_merge_two_sorted_lists/merge_lists.cc +++ b/0021_merge_two_sorted_lists/merge_lists.cc @@ -15,26 +15,21 @@ using namespace std; class Solution { public: ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { - struct ListNode *prev, dummy; - - prev = &dummy; + struct ListNode *tail, dummy; + tail = &dummy; dummy.next = l1; + while (l1 != nullptr && l2 != nullptr) { if (l1->val <= l2->val) { - prev = l1; + tail->next = l1; l1 = l1->next; } else { - struct ListNode *tmp = l2; + tail->next = l2; l2 = l2->next; - tmp->next = l1; - prev->next = tmp; - prev = tmp; } } - if (l2 != nullptr) { - prev->next = l2; - } + tail->next = l1 != nullptr ? l1 : l2; return dummy.next; } diff --git a/0023_merge_k_sorted_lists/merge_lists.c b/0023_merge_k_sorted_lists/merge_lists.c index 3b29dd6..5695b91 100644 --- a/0023_merge_k_sorted_lists/merge_lists.c +++ b/0023_merge_k_sorted_lists/merge_lists.c @@ -2,146 +2,137 @@ #include #include +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * struct ListNode *next; + * }; + */ struct ListNode { int val; struct ListNode *next; }; -struct PriorityQueue { - struct ListNode **nodes; - int size; -}; - static inline void swap(struct ListNode **a, struct ListNode **b) { - struct ListNode *tmp = *a; + struct ListNode *t = *a; *a = *b; - *b = tmp; + *b = t; } -static inline int left(int i) { return i * 2 + 1; } -static inline int right(int i) { return left(i) + 1; } -static inline int parent(int i) { return (i - 1) / 2; } - -static void queue_dump(struct PriorityQueue *queue) +static void min_heapify(struct ListNode **nodes, int size, int parent) { - int i; - for (i = 0; i < queue->size; i++) { - printf("%d ", queue->nodes[i]->val); - } - printf("\n"); -} + int i = parent; /* parent is the root */ + int l = parent * 2 + 1; + int r = parent * 2 + 2; -static void percolate_up(struct ListNode **nodes, int i) -{ - while (i >= 0 && nodes[parent(i)]->val > nodes[i]->val) { - swap(nodes + parent(i), nodes + i); - i = parent(i); + if (l < size && nodes[l]->val < nodes[i]->val) { + i = l; } -} -static void percolate_down1(struct ListNode **nodes, int size, int child) -{ - int i, min; - for (i = child; i >= 0; i = parent(i)) { - if (right(i) < size) { - min = nodes[left(i)]->val < nodes[right(i)]->val ? left(i) : right(i); - } else { - min = left(i); - } - if (nodes[min]->val < nodes[i]->val) { - swap(nodes + min, nodes + i); - } else { - break; - } + if (r < size && nodes[r]->val < nodes[i]->val) { + i = r; } -} -static void percolate_down2(struct ListNode **nodes, int size) -{ - int i, min; - for (i = 0; left(i) < size; i = min) { - if (right(i) < size) { - min = nodes[left(i)]->val < nodes[right(i)]->val ? left(i) : right(i); - } else { - min = left(i); - } - if (nodes[min]->val < nodes[i]->val) { - swap(nodes + min, nodes + i); - } else { - break; - } + /* percolate up */ + if (i != parent) { + swap(&nodes[i], &nodes[parent]); + min_heapify(nodes, size, i); } } -static void heap_build(struct PriorityQueue *queue) +static void build_min_heap(struct ListNode **nodes, int size) { int i; - for (i = queue->size / 2 - 1; i > 0; i--) { - percolate_down1(queue->nodes, queue->size, i); + + if (size <= 0) return; + + for (i = size / 2; i >= 0; i--) { + min_heapify(nodes, size, i); } } -static void put(struct PriorityQueue *queue, struct ListNode *node) +static struct ListNode *get(struct ListNode **nodes, int size) { - queue->nodes[queue->size++] = node; - percolate_up(queue->nodes, queue->size - 1); + struct ListNode *p = nodes[0]; + nodes[0] = nodes[--size]; + min_heapify(nodes, size, 0); + return p; } -static struct ListNode *get(struct PriorityQueue *queue) +static void put(struct ListNode **nodes, int size, struct ListNode *n) { - int i; - struct ListNode *p = queue->nodes[0]; - swap(queue->nodes, queue->nodes + queue->size - 1); - queue->size--; - percolate_down2(queue->nodes, queue->size); - return p; + nodes[size++] = n; + build_min_heap(nodes, size); } -static struct PriorityQueue *init(int size) +static struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) { - struct PriorityQueue *queue = malloc(sizeof(*queue)); - queue->nodes = malloc(size * sizeof(*queue->nodes)); - queue->size = 0; - return queue; + struct ListNode dummy; + struct ListNode *tail = &dummy; + + while (l1 != NULL && l2 != NULL) { + if (l1->val <= l2->val) { + tail->next = l1; + l1 = l1->next; + } else { + tail->next = l2; + l2 = l2->next; + } + tail = tail->next; + } + + tail->next = l1 != NULL ? l1 : l2; + + return dummy.next; } -static struct ListNode* mergeKLists(struct ListNode** lists, int listsSize) +static struct ListNode* dfs(struct ListNode** lists, int lo, int hi) { - if (listsSize == 0) { - return NULL; - } + if (lo > hi) // listsSize might be zero + return NULL; - if (listsSize == 1) { - return lists[0]; - } + if (lo == hi) + return lists[lo]; - int i; - struct ListNode dummy; - struct ListNode *prev; - struct PriorityQueue *queue = init(listsSize); + int mid = lo + (hi - lo) / 2; + return mergeTwoLists(dfs(lists, lo, mid), dfs(lists, mid + 1, hi)); +} - dummy.next = NULL; - prev = &dummy; + +struct ListNode* mergeKLists(struct ListNode** lists, int listsSize) +{ +#if 1 + return dfs(lists, 0, listsSize - 1); +#else + int i, size = 0; + struct ListNode dummy; + struct ListNode *p = &dummy; + struct ListNode **nodes = malloc(listsSize * sizeof(struct ListNode)); for (i = 0; i < listsSize; i++) { if (lists[i] != NULL) { - put(queue, lists[i]); + nodes[size++] = lists[i]; } } - heap_build(queue); - while (queue->size > 0) { - struct ListNode *n = get(queue); - prev->next = n; - prev = n; + build_min_heap(nodes, size); + + while (size > 0) { + struct ListNode *n = get(nodes, size); + size--; + p->next = n; + p = p->next; if (n->next != NULL) { - put(queue, n->next); + put(nodes, size, n->next); + size++; } n->next = NULL; } return dummy.next; +#endif } int main(void) diff --git a/0152_maximum_product_subarray/subarray.c b/0152_maximum_product_subarray/subarray.c index cabe83d..3af1389 100644 --- a/0152_maximum_product_subarray/subarray.c +++ b/0152_maximum_product_subarray/subarray.c @@ -2,6 +2,7 @@ #include #include + static inline int min(int a, int b) { return a < b ? a : b; @@ -31,8 +32,6 @@ static int maxProduct(int* nums, int numsSize) int main(int argc, char **argv) { - - int i, count = argc - 1; int *nums = malloc(count * sizeof(int)); for (i = 0; i < count; i++) { diff --git a/0153_find_minimum_in_rotated_sorted_array/minimum.c b/0153_find_minimum_in_rotated_sorted_array/minimum.c index 1073f1f..677d426 100644 --- a/0153_find_minimum_in_rotated_sorted_array/minimum.c +++ b/0153_find_minimum_in_rotated_sorted_array/minimum.c @@ -6,17 +6,15 @@ static int findMin(int* nums, int numsSize) { int lo = 0; int hi = numsSize - 1; - int min = INT_MAX; - while (lo <= hi) { + while (lo < hi) { int mid = lo + (hi - lo) / 2; - min = min < nums[mid] ? min : nums[mid]; - if (nums[mid] > nums[hi]) { - lo = mid + 1; + if (nums[mid] < nums[hi]) { + hi = mid; } else { - hi = mid - 1; + lo = mid + 1; } } - return min; + return nums[lo]; } int main(int argc, char **argv) diff --git a/0154_find_minimum_in_rotated_sorted_array_ii/minimum.c b/0154_find_minimum_in_rotated_sorted_array_ii/minimum.c index a1ec893..6e11f26 100644 --- a/0154_find_minimum_in_rotated_sorted_array_ii/minimum.c +++ b/0154_find_minimum_in_rotated_sorted_array_ii/minimum.c @@ -3,16 +3,21 @@ static int findMin(int* nums, int numsSize) { - if (numsSize == 1) { - return nums[0]; - } - int i, j; - for (i = 1; i < numsSize; i++) { - if (nums[i] < nums[i - 1]) { - return nums[i]; + int lo = 0; + int hi = numsSize - 1; + + while (lo < hi) { + int mid = lo + (hi - lo) / 2; + if (nums[mid] < nums[hi]) { + hi = mid; + } else if (nums[mid] > nums[hi]) { + lo = mid + 1; + } else { + hi--; } } - return nums[0]; + + return nums[lo]; } int main(int argc, char **argv)