148. 排序链表
给你链表的头结点 head ,请将其按升序排列并返回 排序后的链表 。
Example
input |
---|
head = [4,2,1,3] |
output |
---|
[1,2,3,4] |
input |
---|
head = [-1,5,3,4,0] |
output |
---|
[-1,0,3,4,5] |
Note
- 在
O
(
n
l
o
g
n
)
O(n log n)
O(nlogn) 时间复杂度和常数级空间复杂度下,对链表进行排序
- 链表中节点的数目在范围
[
0
,
5
×
1
0
4
]
[0, 5×10^4]
[0,5×104] 内
-
−
1
0
5
≤
N
o
d
e
.
v
a
l
≤
1
0
5
-10^5 \leq Node.val \leq 10^5
−105≤Node.val≤105
思路
代码如下
class Solution {
public:
ListNode* sortList(ListNode* head) {
ListNode dummyHead(0);
dummyHead.next = head;
auto p = head;
int length = 0;
while (p) {
++length;
p = p->next;
}
for (int size = 1; size < length; size <<= 1) {
auto cur = dummyHead.next;
auto tail = &dummyHead;
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 dummyHead.next;
}
ListNode* cut(ListNode* head, int n) {
auto p = head;
while (--n && p) {
p = p->next;
}
if (!p) return nullptr;
auto next = p->next;
p->next = nullptr;
return next;
}
ListNode* merge(ListNode* l1, ListNode* l2) {
ListNode dummyHead(0);
auto p = &dummyHead;
while (l1 && l2) {
if (l1->val < l2->val) {
p->next = l1;
p = l1;
l1 = l1->next;
} else {
p->next = l2;
p = l2;
l2 = l2->next;
}
}
p->next = l1 ? l1 : l2;
return dummyHead.next;
}
};