在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。
示例 1:
输入: 4->2->1->3
输出: 1->2->3->4
示例 2:
输入: -1->5->3->4->0
输出: -1->0->3->4->5
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sort-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
基本思路:使用容器,存储信息并排序,然后,在对链表进行赋值。
ListNode* sortList(ListNode* head) {
priority_queue<int,vector<int>,greater<int>> q;
ListNode *cur=head;
while(cur){
q.push(cur->val);
cur=cur->next;
}
cur=head;
while(cur){
cur->val=q.top();
q.pop();
cur=cur->next;
}
return head;
}
基本思路:归并排序,自底向上,先切开列表,再合并。
ListNode *cut(ListNode *head,int n){
ListNode *cur=head;
while(cur&&--n){
cur=cur->next;
}
if(cur==nullptr)
return cur;
ListNode *nextPtr=cur->next;
cur->next=nullptr;
return nextPtr;
}
ListNode *merge(ListNode *l1,ListNode *l2){
ListNode *dummyHead=new ListNode(-1);
auto cur=dummyHead;
while(l1&&l2){
if(l1->val>l2->val){
cur->next=l2;
cur=cur->next;
l2=l2->next;
}
else{
cur->next=l1;
cur=cur->next;
l1=l1->next;
}
}
cur->next=l1?l1:l2;
return dummyHead->next;
}
ListNode* sortList(ListNode* head) {
ListNode *dummyHead=new ListNode(-1);
dummyHead->next=head;
int length=0;
ListNode *cur=head;
while(cur){
length++;
cur=cur->next;
}
for(int step=1;step<length;step<<=1){
auto cur=dummyHead->next;
auto tail=dummyHead;
while(cur){
auto left=cur;
auto right=cut(left,step);
cur=cut(right,step);
tail->next=merge(left,right);
while(tail->next){
tail=tail->next;
}
}
}
return dummyHead->next;
}
基本思路:递归做法,同上,但是使用快慢指针查找中间节点将其分为两半。
ListNode *merge(ListNode *l1,ListNode *l2){
ListNode *dummyHead=new ListNode(-1);
auto cur=dummyHead;
while(l1&&l2){
if(l1->val>l2->val){
cur->next=l2;
cur=cur->next;
l2=l2->next;
}
else{
cur->next=l1;
cur=cur->next;
l1=l1->next;
}
}
cur->next=l1?l1:l2;
return dummyHead->next;
}
ListNode *getMiddleNode(ListNode *head){
ListNode *fast=head->next->next,*slow=head; //确保返回的是前半部分的尾指针。
while(fast&&fast->next){
slow=slow->next;
fast=fast->next->next;
}
return slow;
}
ListNode* sortList(ListNode* head) {
if(head==nullptr||head->next==nullptr)
return head;
ListNode *middleNode=getMiddleNode(head);
ListNode *rightHead=middleNode->next;
middleNode->next=nullptr; //断开。
ListNode *left=sortList(head);
ListNode *right=sortList(rightHead);
return merge(left,right);
}
总结:其实并不算常数空间的时间复杂度;