题目描述
在 O(n log n) 时间、尽量 O(1) 额外空间内排序链表。
输入 = 4→2→1→3
输出 = 1→2→3→4
思路解析
关键不是背模板,而是看懂为什么这题适合链表 · 归并排序。
1. 快慢指针找到中点:快慢指针找到中点
2. 从中点断开,分成左右两段:从中点断开,分成左右两段
3. 递归排序左半段:递归排序左半段
4. 递归排序右半段:递归排序右半段
5. 两段各自有序后开始合并:两段各自有序后开始合并
6. 比较两个头节点,小的接到结果后面:比较两个头节点,小的接到结果后面
7. 不断接小节点:不断接小节点
8. 合并完成得到有序链表:合并完成得到有序链表
把这句话记住,下次遇到同类题,就能更快选出方向。
用一个小问题检查自己是不是真的懂了。
参考代码(Python)
Python
1class Solution:
2 def sortList(self, head):
3 if not head or not head.next:
4 return head
5 slow, fast = head, head.next
6 while fast and fast.next:
7 slow = slow.next
8 fast = fast.next.next
9 mid = slow.next
10 slow.next = None
11 left = self.sortList(head)
12 right = self.sortList(mid)
13 return self.merge(left, right)
14 def merge(self, a, b):
15 dummy = tail = ListNode(0)
16 while a and b:
17 if a.val < b.val:
18 tail.next, a = a, a.next
19 else:
20 tail.next, b = b, b.next
21 tail = tail.next
22 tail.next = a or b
23 return dummy.next复杂度分析
- 时间复杂度:O(n log n) —— 每个核心状态按算法要求处理固定次数
- 空间复杂度:O(log n) —— 只保存必要的辅助结构或递归栈
套路模板
模板不是死背,而是提醒你写代码前先把状态、转移和边界排好。
Python
1# 链表 · 归并排序 通用检查表
2# 1. 定义状态/指针/容器
3# 2. 每轮只做一个清晰动作
4# 3. 更新答案并处理边界易错点
- 错误写法:用数组排序后重建 → 正确写法:链表排序的核心是切半和原地合并(数组法绕开了链表训练点)
- 错误写法:只按样例推代码 → 正确写法:先写清状态含义和边界条件(样例太少,隐藏用例专打边界)
- 错误写法:变量名和动画不一致 → 正确写法:代码变量沿用动画里的核心名字(学习时最怕脑内维护两套概念)
以上文字与上方动画完全同一思路:先看动画建立直觉 → 读文字巩固 → 关掉页面自己默写一遍代码,能写出来才算真的掌握。