给定链表的头结点 head
,请将其按 升序 排列并返回 排序后的链表 。
进阶:你可以在 O(n log n)
时间复杂度和常数级空间复杂度下,对链表进行排序吗?
题目分析:
1、由于时间复杂度的要求,选择归并排序
2、需要把链表分为前后两个部分 分别进行归并排序后 合并链表
3、需要实现的函数:split链表, Merge两个链表
---- split链表部分:采用slow fast指针的方式找到中间节点 并且返回
-----Merge链表的部分:比较两部分链表节点的大小 cur指向val小的节点 并且指针后移 最后返回合并后的链表头结点
具体代码如下:
/**
* 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 {
ListNode* find_mid(ListNode* head) {
ListNode* slow = head;
ListNode* fast = head;
while(fast != nullptr && fast->next != nullptr && fast->next->next != nullptr) {
slow = slow -> next;
fast = fast -> next -> next;
}
ListNode* midhead = slow -> next;
slow -> next = nullptr;
return midhead;
}
ListNode* Merge(ListNode* head1, ListNode* head2) {
ListNode* dummyhead = new ListNode(-1);
ListNode* cur = dummyhead;
while(head1 != nullptr && head2 != nullptr) {
if(head1->val < head2-> val) {
cur->next = head1;
head1 = head1->next;
} else {
cur->next = head2;
head2 = head2 -> next;
}
cur = cur -> next;
}
if(head1 != nullptr) cur -> next = head1;
else cur -> next = head2;
ListNode* res = dummyhead -> next;
delete dummyhead;
dummyhead = nullptr;
return res;
}
public:
ListNode* sortList(ListNode* head) {
if(head == nullptr || head -> next == nullptr) return head;
ListNode* head1 = head;
ListNode* head2 = find_mid(head);
head1 = sortList(head1);
head2 = sortList(head2);
return Merge(head1, head2);
}
};