题目描述
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
思路
归并排序,递归和迭代两种方式。递归的空间复杂度为 O(log(n)),迭代的空间复杂度为O(1)。时间复杂度都是 O(nlog(n))。
代码
迭代:
/**
* 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 || head->next == NULL) 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;
tail = &dummy;
while(cur) {
l = cur;
r = split(cur, n);
cur = split(r, n);
auto merged = merge(l, r);
tail->next = merged.first;
tail = merged.second;
}
}
return dummy.next;
}
private:
ListNode* split(ListNode* head, int n) {
while(--n && head)
head = head->next;
ListNode* rest = head ? head->next : NULL;
if (head) head->next = NULL;
return rest;
}
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};
}
};
递归:
/**
* 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 || !head->next) return head;
ListNode* slow = head;
ListNode* fast = head->next;
while(fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
}
ListNode* mid = slow->next;
slow->next = NULL;
return merge(sortList(head), sortList(mid));
}
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;
return dummy.next;
}
};
抄的。。。