一、为什么链表需要"二分"
Mermaid · 渲染中(下方为源码)
graph LR A[链表] --> B[快慢指针] B --> C[定位中点] C --> D[链表分治/归并]
数组可以 O(1) 随机访问,直接 mid = (lo + hi) / 2。链表不行——但快慢指针提供了链表的"二分定位"能力:
| 数组二分 | 链表等价 |
|---|---|
mid = (lo+hi)/2 | 快慢指针找中点 |
| 分治递归 | 中点断开 → 递归两半 |
| O(log n) 定位 | O(n) 定位(但总复杂度不变) |
核心模式:找中点 → 断开 → 递归处理两半 → 合并。这是链表上所有分治算法的骨架。
二、基础:找中点并断开
function splitInHalf(head: ListNode): [ListNode, ListNode] {
let slow = head, fast = head.next; // fast 从 head.next 出发
while (fast && fast.next) {
slow = slow!.next;
fast = fast.next.next;
}
const second = slow!.next;
slow!.next = null; // 断开
return [head, second!];
}fast 从 head.next 出发的原因:偶数个节点时,slow 停在前半段末尾(保证前半段 ≥ 后半段),避免无限递归。