题目描述:
题号:148
给你链表的头结点 head
,请将其按 升序 排列并返回 排序后的链表 。
解题思路:
思路一:归并排序
1、找到中间节点(可以利用前面链表题中的函数)
2、分割链表:首先检查链表是否为空或只有一个节点,如果是,则直接返回该链表,因为无需排序。
然后,将链表从中间分成两部分。分割是通过将中间节点的 next 指针设为 nullptr 来实现的,从而得到两个独立的子链表。
3、递归排序子链表:对分割后的两个子链表(左子链表和右子链表)分别递归调用 sortList 函数进行排序。
这是归并排序算法的核心步骤之一,将大问题分解为小问题。
4、有序合并排序后的链表
时间复杂度:O(N logN)
空间复杂度:O(logN)
C++
// C++
/**
* 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* midList(ListNode* head) {
if(head == nullptr || head->next == nullptr) {
return head;
}
ListNode *fast = head;
ListNode *slow = head;
while(fast->next != nullptr && fast->next->next != nullptr) {
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
ListNode* mergeList(ListNode* head1, ListNode* head2) {
if(head1 == nullptr && head2 == nullptr) {
return nullptr;
}
unique_ptr<ListNode> dummyHead (new ListNode(99999));
ListNode* cur = dummyHead.get();
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 || head2 != nullptr) {
cur->next = head1 == nullptr ? head2 : head1;
}
return dummyHead->next;
}
public:
ListNode* sortList(ListNode* head) {
if(head == nullptr || head->next == nullptr) {
return head;
}
// chaifen
ListNode *mid = midList(head);
ListNode *left = head;
ListNode *right = mid->next;
mid->next = nullptr;
// liangbiandigui
ListNode *lHead = sortList(left);
ListNode *rHead = sortList(right);
// hebing
ListNode *newHead = mergeList(lHead, rHead);
return newHead;
}
};
go
// go
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func sortList(head *ListNode) *ListNode {
// 递归结束条件
if head == nil || head.Next == nil {
return head
}
// 先找到中间节点
mid := middleNode(head)
// 拆分左右两个链条
left := head
right := mid.Next
mid.Next = nil
// 两边递归排序
lHead := sortList(left)
rHead := sortList(right)
// 合并有序链表
mergeHead := mergeTwoLists(lHead, rHead)
return mergeHead
}
// 返回链表中间节点,如果节点个数是偶数,则返回第一个中间节点
func middleNode(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return head
}
slow := head
fast := head
for fast.Next != nil && fast.Next.Next != nil {
fast = fast.Next.Next
slow = slow.Next
}
return slow
}
// 合并两个有序的链表
func mergeTwoLists(list1, list2 *ListNode) *ListNode {
list3 := &ListNode{-1, nil}
temp := list3
for list1 != nil && list2 != nil {
if list1.Val <= list2.Val {
temp.Next = list1
list1 = list1.Next
} else {
temp.Next = list2
list2 = list2.Next
}
temp = temp.Next
}
if list1 == nil {
temp.Next = list2
} else {
temp.Next = list1
}
return list3.Next
}