在 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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
先用递归形式的归并排序,题目要求时间复杂度是O(NlogN)就要想到二分,也就是归并了,然后递归的话也需要空间复杂度O(logN),特别注意一个点是用快慢指针找重点快指针需要先走一步,才能保证双中点的时候找到前一个位置。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* sortList(ListNode* head) {
//使用递归归并排序
if(head == nullptr || head->next == nullptr)
return head;
//使用快慢指针来找出中点
//fast先提前一个位置,才能让slow处在双中点的前一个位置
ListNode *fast = head->next,*slow = head;
while(fast != nullptr && fast->next != nullptr){
slow = slow->next;
fast = fast->next->next;
}
ListNode *newHead = slow->next;
slow->next = nullptr;
//找到中点后,就递归
ListNode *left = sortList(head);
ListNode *right = sortList(newHead);
ListNode *tmp = nullptr;
ListNode *retHead = nullptr;
//然后归并
while(left != nullptr && right != nullptr){
if(left->val < right->val){
if(tmp == nullptr){
tmp = left;
retHead = left;
}
else{
tmp->next = left;
tmp = left;
}
left = left->next;
tmp->next = nullptr;
}else{
if(tmp == nullptr){
tmp = right;
retHead = right;
}
else{
tmp->next = right;
tmp = right;
}
right = right->next;
tmp->next = nullptr;
}
}
while(left != nullptr){
tmp->next = left;
tmp = left;
left = left->next;
tmp->next = nullptr;
}
while(right != nullptr){
tmp->next = right;
tmp = right;
right = right->next;
tmp->next = nullptr;
}
return retHead;
}
};