From 87a25357046ae8680837fdcc8aed9a34574aa611 Mon Sep 17 00:00:00 2001 From: Kuang Qin Date: Sun, 26 Mar 2017 15:32:14 -0500 Subject: [PATCH 1/2] Add Solution for 148 Sort List --- cpp/148_Sort_List.cpp | 75 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 cpp/148_Sort_List.cpp diff --git a/cpp/148_Sort_List.cpp b/cpp/148_Sort_List.cpp new file mode 100644 index 0000000..331b336 --- /dev/null +++ b/cpp/148_Sort_List.cpp @@ -0,0 +1,75 @@ +// 148. Sort List +/** + * Sort a linked list in O(n log n) time using constant space complexity. + * + * Tags: Linked List, Sort + * + * Similar Problems: (E) Merge Two Sorted Lists, (M) Sort Colors, (M) Insertion Sort List + * + * Author: Kuang Qin +*/ + +#include + +using namespace std; + +/** + * Definition for singly-linked list. + */ +struct ListNode { + int val; + ListNode *next; + ListNode(int x) : val(x), next(NULL) {} + ListNode(int x, ListNode *p) : val(x), next(p) {} +}; + +class Solution { + ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { + if (l1 == NULL) { + return l2; + } + + if (l2 == NULL) { + return l1; + } + + if (l1->val < l2->val) { // the first element from l1 + l1->next = mergeTwoLists(l1->next, l2); + return l1; + } + + // first element from l2 + l2->next = mergeTwoLists(l2->next, l1); + return l2; + } + +public: + ListNode* sortList(ListNode* head) { + if (head == NULL || head->next == NULL) { + return head; + } + + ListNode *slow = head, *fast = head->next; + while (fast != NULL && fast->next != NULL) { + slow = slow->next; + fast = fast->next->next; + } + + ListNode *l1 = head, *l2 = slow->next; + slow->next = NULL; + return mergeTwoLists(sortList(l1), sortList(l2)); + } +}; + +int main() { + ListNode node5(3), node4(1, &node5), node3(5, &node4), node2(4, &node3), node1(2, &node2); + Solution sol; + ListNode *newhead = sol.sortList(&node1); + for (ListNode *p = newhead; p != NULL; p = p->next) { + cout << p->val << " "; + } + cout << endl; + cin.get(); + + return 0; +} \ No newline at end of file From 923347b3396a4648153d9204a2e8334707995272 Mon Sep 17 00:00:00 2001 From: Kuang Qin Date: Sun, 26 Mar 2017 16:03:25 -0500 Subject: [PATCH 2/2] Add Bottom-up Merge Sort Solution --- cpp/148_Sort_List.cpp | 87 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/cpp/148_Sort_List.cpp b/cpp/148_Sort_List.cpp index 331b336..f3aa823 100644 --- a/cpp/148_Sort_List.cpp +++ b/cpp/148_Sort_List.cpp @@ -23,6 +23,8 @@ struct ListNode { ListNode(int x, ListNode *p) : val(x), next(p) {} }; +// top-down merge sort +// time: O(nlogn), space: O(logn) class Solution { ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { if (l1 == NULL) { @@ -61,6 +63,91 @@ class Solution { } }; +// bottom-up merge sort +// time: O(nlogn), space: O(1) +class Solution_BottomUp { + // divide the list into two part, return the head of the second part + ListNode* split(ListNode* head, int n) { + for (int i = 1; head != NULL && i < n; i++) { + head = head->next; + } + + if (head != NULL) { + // remaining part of the list + ListNode *p = head->next; + head->next = NULL; + return p; + } + + // head == NULL + return NULL; + } + + // merge two sorted list l1 and l2, then append the result to head + // return the tail of the merged list + ListNode* merge(ListNode* l1, ListNode* l2, ListNode* head) { + ListNode *curr = head; + + while (l1 != NULL && l2 != NULL) { + if (l1->val > l2->val) { + curr->next = l2; + curr = l2; + l2 = l2->next; + } + else { + curr->next = l1; + curr = l1; + l1 = l1->next; + } + } + + // append the rest of the list + curr->next = (l1 != NULL) ? l1 : l2; + + // go to the tail of the list + while (curr->next != NULL) { + curr = curr->next; + } + + return curr; + } + +public: + ListNode* sortList(ListNode* head) { + if (head == NULL || head->next == NULL) { + return head; + } + + // get length + ListNode *curr = head; + int length = 0; + while (curr != NULL) { + curr = curr->next; + length++; + } + + ListNode dummy(0); + dummy.next = head; + + ListNode *left, *right, *tail; + for (int step = 1; step < length; step <<= 1) { + // for each new step, set curr to the beginning of the list + curr = dummy.next; + tail = &dummy; + + // traverse the entire list once + while (curr != NULL) { + left = curr; + right = split(left, step); + curr = split(right, step); + tail = merge(left, right, tail); + } + } + + return dummy.next; + } +}; + int main() { ListNode node5(3), node4(1, &node5), node3(5, &node4), node2(4, &node3), node1(2, &node2); Solution sol;