排序链表
-
- [题解1 STL - multiset](#题解1 STL - multiset)
- [题解2 归并【自顶向下】](#题解2 归并【自顶向下】)
- [题解3 归并【自底向上】](#题解3 归并【自底向上】)
-
- [自底向上:子串长度 l 从1开始,合并后的串长度*2,1+1 -> 2+2 -> 4+4 ->...](#自底向上:子串长度 l 从1开始,合并后的串长度*2,1+1 -> 2+2 -> 4+4 ->...)
给你链表的头结点 head
,请将其按 升序 排列并返回 排序后 的链表 。
提示:
- 链表中节点的数目在范围 [0, 5 ∗ 1 0 4 5 * 10^4 5∗104] 内
- − 1 0 5 -10^5 −105 <=
Node.val
<= 1 0 5 10^5 105
进阶:你可以在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序吗?
建议用vscode时间测试,分别转成数组排序和只在链表基础上操作
题解1 STL - multiset
cpp
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* sortList(ListNode* head) {
if(!head || !head->next) return head;
ListNode* subhead = head;
multiset<int> kkset;
while(subhead){
kkset.insert(subhead->val);
subhead = subhead->next;
}
subhead = head;
// 直接改值
for(auto& i : kkset){
subhead->val = i;
subhead = subhead->next;
}
subhead = nullptr;
return head;
}
};
题解2 归并【自顶向下】
cpp
class Solution {
public:
// 递归
ListNode* mergesort(ListNode* head, ListNode* tail){
if(! head || head->next == tail){
// 不含tail
if(head) head->next = nullptr;
return head;
}
// 找到head和tail之间的中点(slow)
ListNode *fast, *slow;
fast = slow = head;
while(fast != tail){
slow = slow->next;
fast = fast->next;
if(fast != tail)
fast = fast->next;
}
// ListNode* midnode = slow;
// recursion
// return merge(mergesort(head, midnode), mergesort(midnode, tail));
return merge(mergesort(head, slow), mergesort(slow, tail));
}
ListNode* sortList(ListNode* head) {
return mergesort(head, nullptr);
}
// 21.合并两个有序链表
ListNode* merge(ListNode*l1, ListNode* l2){
ListNode* dummynode = new ListNode(0);
ListNode *p = dummynode;
dummynode->next = p;
while(l1 || l2){
if(l1){
if(l2 && l1->val <= l2->val){
p->next = l1;
p = p->next;
l1 = l1->next;
continue;
}
if(!l2){
p->next = l1;
break;
}
}
if(l2){
if(l1 && l2->val < l1->val){
p->next = l2;
p = p->next;
l2 = l2->next;
continue;
}
if(!l1){
p->next = l2;
break;
}
}
}
return dummynode->next;
}
};
题解3 归并【自底向上】
自底向上:子串长度 l 从1开始,合并后的串长度*2,1+1 -> 2+2 -> 4+4 ->...
cpp
// 有时间自己再写一遍
class Solution {
public:
ListNode* sortList(ListNode* head) {
if (head == nullptr) {
return head;
}
int length = 0;
ListNode* node = head;
while (node != nullptr) {
length++;
node = node->next;
}
ListNode* dummyHead = new ListNode(0, head);
for (int subLength = 1; subLength < length; subLength <<= 1) {
ListNode* prev = dummyHead, *curr = dummyHead->next;
while (curr != nullptr) {
ListNode* head1 = curr;
for (int i = 1; i < subLength && curr->next != nullptr; i++) {
curr = curr->next;
}
ListNode* head2 = curr->next;
curr->next = nullptr;
curr = head2;
for (int i = 1; i < subLength && curr != nullptr && curr->next != nullptr; i++) {
curr = curr->next;
}
ListNode* next = nullptr;
if (curr != nullptr) {
next = curr->next;
curr->next = nullptr;
}
ListNode* merged = merge(head1, head2);
prev->next = merged;
while (prev->next != nullptr) {
prev = prev->next;
}
curr = next;
}
}
return dummyHead->next;
}
ListNode* merge(ListNode* head1, ListNode* head2) {
ListNode* dummyHead = new ListNode(0);
ListNode* temp = dummyHead, *temp1 = head1, *temp2 = head2;
while (temp1 != nullptr && temp2 != nullptr) {
if (temp1->val <= temp2->val) {
temp->next = temp1;
temp1 = temp1->next;
} else {
temp->next = temp2;
temp2 = temp2->next;
}
temp = temp->next;
}
if (temp1 != nullptr) {
temp->next = temp1;
} else if (temp2 != nullptr) {
temp->next = temp2;
}
return dummyHead->next;
}
};