Sort a linked list in O(n log n) time using constant space complexity.
符合O(n log n)复杂度的算法有快速排序、桶排序、归并排序。其中快速排序需要交换元素不适用于列表;桶排序的空间复杂度为O(n);由于列表的特性,归并排序满足时间、空间复杂度。
唯一的难点就在于如何将列表二分。这里用到了快慢指针的方法:slow指针每次前进一步,fast指针前进两步,这样当fast停止时slow指向了后一半的首个节点。
代码如下:
class Solution {
public:
ListNode* sortList(ListNode* head) {
if (!head || !head->next) return head;
ListNode *slow = head, *fast = head, *pre = head;
while (fast && fast->next){
pre = slow;
slow = slow->next;
fast = fast->next->next;
}
pre->next = nullptr;
return merge(sortList(head), sortList(slow));
}
ListNode *merge(ListNode *l1, ListNode *l2){
ListNode *dummy = new ListNode(-1);
ListNode *cur = dummy;
while (l1&&l2){
if (l1->val < l2->val){
cur->next = l1;
l1 = l1->next;
}
else{
cur->next = l2;
l2 = l2->next;
}
cur = cur->next;
}
if (l1) cur->next = l1;
if (l2) cur->next = l2;
return dummy->next;
}
};