给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。
进阶:
你可以在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序吗?
示例 1:
输入:head = [4,2,1,3]
输出:[1,2,3,4]
示例 2:
输入:head = [-1,5,3,4,0]
输出:[-1,0,3,4,5]
示例 3:
输入:head = []
输出:[]
提示:
链表中节点的数目在范围 [0, 5 * 104] 内
-105 <= Node.val <= 105
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sort-list
解法一:
以前没怎么写过归并排序,花的时间有点久,归并排序递归版,需要掌握快慢指针,有序链表的合并。
/**
* 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) {
return getSortList(head);
}
ListNode* getSortList(ListNode* head)
{
if (head==nullptr||head->next==nullptr)
{
return head;
}
ListNode* fast = head->next;
ListNode* slow = head;
while (fast!=nullptr&&fast->next!=nullptr)
{
slow = slow->next;
fast = fast->next;
if (fast!=nullptr)
fast = fast->next;
}
ListNode* temp = slow->next;
slow->next = nullptr;
ListNode* list1 = sortList(head);
ListNode* list2 = sortList(temp);
return mergeList(list1, list2);
}
ListNode* mergeList(ListNode* head1, ListNode* head2)
{
ListNode* head = new ListNode(0);
ListNode* q = head;
while (head1&&head2)
{
if (head1->val < head2->val)
{
q->next = head1;
head1 = head1->next;
}
else
{
q->next = head2;
head2 = head2->next;
}
q = q->next;
}
if (head1)q->next = head1;
if (head2)q->next = head2;
return head->next;
}
};
解法二:
使用迭代版的归并排序,用于链表代码繁琐,调试了好久,虽然通过了,但没有官方写的简洁,精妙,又根据官方的进行修改。链表中当进行了cur=cur->next,则需要判断cur是否为空。
/**
* 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 == nullptr || head->next == nullptr)
return head;
ListNode* p = head;
int len = 0;
while (p)
{
len++;
p = p->next;
}
ListNode* dummyHead = new ListNode(0, head);
for (int sublength = 1; sublength < len; sublength <<= 1)
{
ListNode* cur = dummyHead->next;
ListNode* pre = dummyHead;
while (cur)
{
ListNode* head1 = cur;
for (int i = 1; i < sublength&&cur->next!= nullptr; i++)
{
cur = cur->next;
}
ListNode* head2 = nullptr;
head2=cur->next;
cur->next = nullptr;
cur = head2;
if(cur!=nullptr)
{
for (int i = 1; i < sublength&&cur!=nullptr&&cur->next != nullptr; i++)
{
cur = cur->next;
}
}
if(cur!=nullptr)
{
ListNode* next = cur->next;
cur->next = nullptr;
cur=next;
}
pre->next=mergeList(head1, head2);
while (pre->next)
{
pre = pre->next;
}
}
}
return dummyHead->next;
}
ListNode* mergeList(ListNode* head1, ListNode* head2)
{
ListNode* head = new ListNode(0);
ListNode* q = head;
while (head1&&head2)
{
if (head1->val < head2->val)
{
q->next = head1;
head1 = head1->next;
}
else
{
q->next = head2;
head2 = head2->next;
}
q = q->next;
}
if (head1)q->next = head1;
if (head2)q->next = head2;
return head->next;
}
};