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};
}
};