在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。
示例 1:
输入: 4->2->1->3
输出: 1->2->3->4
示例 2:
输入: -1->5->3->4->0
输出: -1->0->3->4->5
二分归并法对链表进行排序
1. 首先通过快慢指针把链表拆成前后两半部分。 2. 对前后两半部分分别进行排序。 3.合并两个有序链表。
时间复杂度分析:拆分时间O(n),两部分运算时间2T(n/2),合并时间O(n)
T(n)=2T(n/2)+2O(n),根据主定理,T(n)=nlogn
空间复杂度分析:空间复杂度一般是指除了输入输出之外额外的部分:这个题没有new一个新的指针,所以空间复杂度O(1)。但是如果要是数组的话,二分归并空间复杂度O(n),因为合并数组的时候,如果还是占用原来的空间的话,原来的数就不知道放哪儿了。链表的话,我们只需要更改指针的指向就行了。
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode *dummy=new ListNode (0), *p=dummy;
while(l1 && l2){
if(l1->val >= l2->val){
p->next=l2;
l2=l2->next;
}
else{
p->next=l1;
l1=l1->next;
}
p=p->next;
}
if(l1) p->next=l1;
if(l2) p->next=l2;
return dummy->next;
}
ListNode* sortList(ListNode* head) {
if(!head || !head->next) return head;
ListNode *fast=head, *slow=head, *pre=head;
while(fast && fast->next){
pre=slow;
slow=slow->next;
fast=fast->next->next;
}
pre->next=nullptr;
head=sortList(head);
slow=sortList(slow);
return mergeTwoLists(head,slow);
}
};