最快定位链表中间节点的方法是快慢指针法:slow每次走1步、fast每次走2步,二者从头出发,当fast为null或fast.next为null时停止,此时slow即指向中间节点(偶数长度时为第二个中间节点),时间复杂度O(n),空间复杂度O(1)。
最快定位链表中间节点,核心不是“算长度”,而是让两个指针以不同速度同步移动——利用它们的位移差自然收敛到中点。这个思路不依赖链表总长,一次遍历就能完成,时间复杂度稳定在 o(n),空间开销仅需两个指针变量。
快慢指针的基本逻辑
设 slow 每次走 1 步,fast 每次走 2 步,二者从头节点同时出发。由于 fast 的速度是 slow 的两倍,在相同时间内,fast 走过的节点数始终是 slow 的两倍。当 fast 到达链表尾部(null)或无法再走两步(fast.next == null)时,slow 恰好走到中间位置。
- 链表长度为奇数(如 5):fast 最终停在最后一个节点,slow 停在第 3 个节点(正中间)
- 链表长度为偶数(如 4):fast 在第 2 个节点后无法继续走两步(fast.next.next == null),此时 slow 停在第 3 个节点——即两个中间节点中的后一个
关键边界判断不能错位
循环条件必须写作 while (fast != null && fast.next != null),且顺序不可调换。因为要先确认 fast 本身非空,才能安全访问 fast.next;否则在 fast 已为 null 时直接取 next 会引发空指针异常。
- 若链表为空(head == null)或仅有一个节点,直接返回 head 即可
- fast 走到最后一个节点时(fast.next == null),循环终止,slow 当前位置就是答案
- fast 走到 null(比如从倒数第二个节点跳两步越界),也意味着循环结束,slow 同样落在中间
为什么比两次遍历更优
两次遍历法需先扫一遍得长度 n,再走 n/2 步——实际最多移动约 1.5n 次节点指针。而快慢指针全程只走 n/2 步(slow 的步数),fast 虽走 n 步,但它是同一轮循环内完成的,不增加额外遍历轮次。
- 代码更紧凑,无长度变量、无二次初始化游标
- 对缓存更友好:节点访问局部性强,减少内存跳跃
- 天然适配流式场景:不需要预先知道链表是否终结,边走边判
其他方法为什么不推荐
数组法需额外 O(n) 空间复制全部节点;哈希表或平衡树法不仅空间更大,还要求链表有序或额外建结构,违背“单次扫描、原地定位”的初衷;二分查找在链表上无法实现 O(log n) 随机访问,实际仍是线性成本。
- 所有替代方案都引入了不必要的空间开销或前提假设
- 快慢指针是唯一满足“无需长度、不改结构、单次遍历、常数空间”的解法
- 面试和工程中,它已是事实标准,理解到位就能稳定写出无 bug 实现

















