1、解题思路
- 归并排序:归并排序是链表排序的最佳选择,因为它满足时间复杂度 O(nlogn) 和空间复杂度 O(n) 的要求。归并排序的核心思想是分治法:将链表分成两半,分别排序,然后合并两个有序链表。
- 步骤:分割链表:使用快慢指针找到链表的中间节点,将链表分成两部分。递归排序:分别对分割后的两部分递归排序。合并有序链表:将两个有序链表合并成一个有序链表。
2、代码实现
C++
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) : val(x), next(nullptr) {}
* };
*/
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类 the head node
* @return ListNode类
*/
ListNode* sortInList(ListNode* head) {
// write code here
// 递归终止条件:空链表或只有一个节点
if (head == nullptr || head->next == nullptr) {
return head;
}
// 使用快慢指针找到中间节点
ListNode* slow = head, *fast = head->next;
while (fast != nullptr && fast->next != nullptr) {
slow = slow->next;
fast = fast->next->next;
}
// 分割链表
ListNode* mid = slow->next;
slow->next = nullptr;
// 递归排序两部分
ListNode* left = sortInList(head);
ListNode* right = sortInList(mid);
// 合并两个有序链表
return merge(left, right);
}
private:
// 合并两个有序链表
ListNode* merge(ListNode* cur1, ListNode* cur2) {
ListNode dummy(0), *cur = &dummy;
while (cur1 && cur2) {
if (cur1->val < cur2->val) {
cur->next = cur1;
cur1 = cur1->next;
} else {
cur->next = cur2;
cur2 = cur2->next;
}
cur = cur->next;
}
// 将剩余部分连接到结果链表
cur->next = (cur1 != nullptr) ? cur1 : cur2;
return dummy.next;
}
};
Java
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* public ListNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类 the head node
* @return ListNode类
*/
public ListNode sortInList (ListNode head) {
// write code here
// 递归终止条件:空链表或只有一个节点
if (head == null || head.next == null) {
return head;
}
// 使用快慢指针找到中间节点
ListNode slow = head, fast = head.next;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
// 分割链表
ListNode mid = slow.next;
slow.next = null;
// 递归排序两部分
ListNode left = sortInList(head);
ListNode right = sortInList(mid);
// 合并两个有序链表
return merge(left, right);
}
// 合并两个有序链表
private ListNode merge(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(-1); // 虚拟头节点
ListNode curr = dummy;
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
curr.next = l1;
l1 = l1.next;
} else {
curr.next = l2;
l2 = l2.next;
}
curr = curr.next;
}
// 将剩余部分连接到结果链表
curr.next = (l1 != null) ? l1 : l2;
return dummy.next;
}
}
Python
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param head ListNode类 the head node
# @return ListNode类
#
class Solution:
def sortInList(self, head: ListNode) -> ListNode:
# write code here
# 递归终止条件:空链表或只有一个节点
if not head or not head.next:
return head
# 使用快慢指针找到中间节点
slow, fast = head, head.next
while fast and fast.next:
slow = slow.next
fast = fast.next.next
# 分割链表
mid = slow.next
slow.next = None
# 递归排序两部分
left = self.sortInList(head)
right = self.sortInList(mid)
# 合并两个有序链表
return self.merge(left, right)
# 合并两个有序链表
def merge(self, l1: ListNode, l2: ListNode) -> ListNode:
dummy = ListNode(-1) # 虚拟头节点
curr = dummy
while l1 and l2:
if l1.val < l2.val:
curr.next = l1
l1 = l1.next
else:
curr.next = l2
l2 = l2.next
curr = curr.next
# 将剩余部分连接到结果链表
curr.next = l1 if l1 else l2
return dummy.next
3、复杂度分析