题目描述
返回单链表的中间结点(偶数个时返回靠后的那个)。
思路解析
先遍历数出长度 n,再从头走 n/2 步——要走两趟。能不能一趟就定位中间?让两个指针一快一慢。
fast 的速度是 slow 的两倍。当 fast 跑到链表末尾(走了 n 步),slow 只走了 n/2 步——正好停在中点。这就是「速度差定位」,很经典的技巧。
起点 · slow=fast=头:slow 和 fast 都从头节点 1 出发。
第 1 步 · slow→2, fast→3:slow 走 1 步到 2,fast 走 2 步到 3。fast 已经把 slow 甩开了。
第 2 步 · slow→3, fast→5:slow 到 3,fast 到 5(最后一个)。fast 再想走两步就出界了,循环将停。
fast 到尾 · slow 即中点:fast 此刻在最后一个节点 5,它的 next 已是 null——循环条件 fast.next 不成立,停止。slow 停在 3,正是中间结点,返回它及其之后 3 → 4 → 5。
若是 1→2→3→4:fast 走 2 步到 3、再走到 null,slow 走到 3——返回靠后的 3。循环条件 while fast and fast.next 天然处理了奇偶两种情况。
快慢指针是链表的万能钥匙:2:1 速度差找中点;同速带偏移找倒数第 k 个;fast 追 slow 判环。记住「两个指针不同步走」这招。
参考代码(Python)
1def middleNode(self, head):
2 slow = fast = head
3 while fast and fast.next: # fast 还能走两步
4 slow = slow.next # 慢走一步
5 fast = fast.next.next # 快走两步
6 return slow # fast 到头,slow 在中间复杂度分析
- 时间复杂度:O(n) —— 一趟就够
- 空间复杂度:O(1) —— 两个指针
套路模板
记住骨架:slow 走 1、fast 走 2、循环条件 fast and fast.next。判环、找环入口、回文链表都从这个骨架变化而来。
1slow = fast = head
2while fast and fast.next: # 防止 fast.next.next 越界
3 slow = slow.next # 1 步
4 fast = fast.next.next # 2 步
5# fast 到头时,slow 在中点易错点
- ❌ 循环条件只写 while fast → ✅ while fast and fast.next(fast.next 为空时再 .next.next 会报错)
- ❌ 先动 fast 再判断 → ✅ 在循环条件里先判,再一起走(保证 fast 跨两步前后都合法)
以上文字与上方动画完全同一思路:先看动画建立直觉 → 读文字巩固 → 关掉页面自己默写一遍代码,能写出来才算真的掌握。