LeetCode 876简单链表 · 快慢指针
链表的中间结点 图解题解
这道题到底在问什么
给定单链表头结点 head,返回中间结点。若有两个中间结点,返回第二个。
- 输入
- 1→2→3→…→9
- 输出
- 5(下标 4)
最优解:一步一步想明白
- 3记住这条比例:fast 是 slow 的两倍速。
- 4出发:slow、fast 都站在头结点(下标 0)。
- 5第 1 轮:slow 向前走 1 格,到下标 1。
- 6同一轮:fast 向前走第 1 格,到下标 1。
- 7fast 再走 1 格(这轮共走 2 格),到下标 2。此刻 fast 跑在 slow 前面整整一倍距离。
- 8第 2 轮:slow 向前走 1 格,到下标 2。
- 9同一轮:fast 向前走第 1 格,到下标 3。
- 10fast 再走 1 格(这轮共走 2 格),到下标 4。此刻 fast 跑在 slow 前面整整一倍距离。
- 11第 3 轮:slow 向前走 1 格,到下标 3。
- 12同一轮:fast 向前走第 1 格,到下标 5。
- 13fast 再走 1 格(这轮共走 2 格),到下标 6。此刻 fast 跑在 slow 前面整整一倍距离。
- 14第 4 轮:slow 向前走 1 格,到下标 4。
- 15同一轮:fast 向前走第 1 格,到下标 7。
- 16fast 再走 1 格(这轮共走 2 格),到下标 8。此刻 fast 跑在 slow 前面整整一倍距离。
- 17fast 再走 2 格就出链了(next 为空),循环停止。slow 停在下标 4 —— 正好是中点,即第 5 个结点,就是答案。
⚠️ 容易写错的地方
✗ 错:while 写成 fast.next && fast
✓ 对:fast 在前:先判 fast 非空再访问 fast.next
顺序反了 fast 为空时访问 .next 会崩
✗ 错:偶数返回了第一个中点
✓ 对:slow=fast=head 起步 → 偶数自然返回第二个
本题要求返回靠后的那个
✗ 错:先遍历数长度再走一半
✓ 对:快慢指针一次搞定
两次遍历多余,快慢指针更优雅
完整代码(Python / C++ / Java)
Python
def middleNode(head):
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
return slowC++
ListNode* middleNode(ListNode* head){
ListNode *slow = head, *fast = head;
while(fast && fast->next){
slow = slow->next;
fast = fast->next->next;
}
return slow;
}Java
public ListNode middleNode(ListNode head){
ListNode slow = head, fast = head;
while(fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
}
return slow;
}复杂度
时间
O(n)
fast 一遍走完即停
空间
O(1)
只用两个指针
看不够?换成动画再走一遍
上面的推演每一步都对应一帧动画。点开交互动画版,能一步步看着 链表的中间结点 的数据怎么变、指针怎么走,还能切 Python / Java / C++ 跟着练。
面试官可能追问
快慢指针还能解什么?+
判断链表有无环(fast 追上 slow 即有环)、找环入口、找倒数第 k 个结点等。
为什么 fast 到尾 slow 正好一半?+
fast 速度是 slow 两倍,走过的距离也是两倍;fast 走完全程 n,slow 自然走了 n/2。
想听吴师兄把这道题讲给你听?
文字版和动画都随便看。开通图解算法年卡,可以听吴师兄把 链表的中间结点 一步步讲透(全站已上线 905 份讲透,持续扩充), 卡住的地方还有 AI 私教小欧就着动画帮你拆到懂。
把这道题真正拿下
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。