- 题目:sort a linked list in O(n log n) time using constant space complexity.
- idea:
- 使用自底向上来归并排序链表,首先将左右两个待合并的链表分别cut切开,即将左右两个链表的结尾节点的next设置为NULL
- 每次合并完两个链表以后将上一个合并完的链表的尾部的next指向当前合并完的链表
/**
* 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) {
int len = 0;
auto p = head;
while(p){
len++;
p = p->next;
}
for (unsigned size = 1; size < len; size *= 2){
auto left = head;
auto right = cut(left, size);
auto cur = cut(right, size);
head = merge(left, right);
auto tail = head;
while (tail->next){
tail = tail->next;
}
int count = 0;
while(cur){
auto left = cur;
auto right = cut(left, size);
cur = cut(right, size);
tail->next = merge(left, right);
while (tail->next){
tail = tail->next;
}
}
}
return head;
}
ListNode* cut(ListNode *p, int size){
while (p && --size){
p = p->next;
}
if (!p) return NULL;
auto res = p->next;
p->next = NULL;
return res;
}
ListNode* merge(ListNode *p1, ListNode *p2){
if (!p2) return p1;
ListNode *head;
if (p1->val < p2->val) head = p1, p1 = p1->next;
else head = p2, p2 = p2->next;
auto p = head;
while (p1 && p2){
if (p1->val < p2->val){
p->next = p1;
p1 = p1->next;
}
else{
p->next = p2;
p2 = p2->next;
}
p = p->next;
}
p->next = p1?p1:p2;
return head;
}
};