148. Sort List
Sort a linked list in O(n log n) time using constant space complexity.
Example 1:
Input: 4->2->1->3 Output: 1->2->3->4
Example 2:
Input: -1->5->3->4->0 Output: -1->0->3->4->5
AC code:
time(O(nlongn) space(O(logn))
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* sortList(ListNode* head) { if (head == NULL || head->next == NULL) return head; ListNode* fast = head->next; ListNode* slow = head; while (fast != NULL && fast->next != NULL) { fast = fast->next->next; slow = slow->next; } ListNode* mid = slow->next; slow->next = NULL; return merge(sortList(head), sortList(mid)); } private: ListNode* merge(ListNode* l1, ListNode* l2) { ListNode dummy(0); ListNode* p = &dummy; while (l1 && l2) { if (l1->val > l2->val) swap(l1, l2); p->next = l1; l1 = l1->next; p = p->next; } if (l1) p->next = l1; if (l2) p->next = l2; return dummy.next; } };
Runtime: 28 ms, faster than 100.00% of C++ online submissions for Sort List.
optimization code:
time:O(nlongn)) space:O(1)
// Author: Huahua // Running time: 32 ms class Solution { public: ListNode* sortList(ListNode* head) { // 0 or 1 element, we are done. if (!head || !head->next) return head; int len = 1; ListNode* cur = head; while (cur = cur->next) ++len; ListNode dummy(0); dummy.next = head; ListNode* l; ListNode* r; ListNode* tail; for (int n = 1; n < len; n <<= 1) { cur = dummy.next; // partial sorted head tail = &dummy; while (cur) { l = cur; r = split(l, n); cur = split(r, n); auto merged = merge(l, r); tail->next = merged.first; tail = merged.second; } } return dummy.next; } private: // Splits the list into two parts, first n element and the rest. // Returns the head of the rest. ListNode* split(ListNode* head, int n) { while (--n && head) head = head->next; ListNode* rest = head ? head->next : nullptr; if (head) head->next = nullptr; return rest; } // Merges two lists, returns the head and tail of the merged list. pair<ListNode*, ListNode*> merge(ListNode* l1, ListNode* l2) { ListNode dummy(0); ListNode* tail = &dummy; while (l1 && l2) { if (l1->val > l2->val) swap(l1, l2); tail->next = l1; l1 = l1->next; tail = tail->next; } tail->next = l1 ? l1 : l2; while (tail->next) tail = tail->next; return {dummy.next, tail}; } };
永远渴望,大智若愚(stay hungry, stay foolish)