倒数第 k 个 与 链表中点
单链表只能从头向后遍历,但实际常要定位「倒数第 k 个」「正中间那个」——两者都依赖总长度信息。朴素做法是先扫一遍得到长度 ,再走 步,需要两趟。双指针把它变成一趟:核心是先让两指针拉开一段固定间距,再让它们同速齐步走,前指针到尾时,后指针恰好停在目标位置。下面两道题用的是同一思路。
倒数第 k 的关键是「固定间距」:让 fast 先独走
步,这时 fast 与 slow 之间永远隔着
条边。两者再一起走,等 fast 跨出表尾 (null),slow 与表尾的距离也正好是
——它就停在倒数第 k 个。常见应用:删除倒数第 k 个节点,slow 与 fast 都从 哨兵 dummy(见 链表基础)起、fast 先走
步,结束时 slow 恰好停在待删节点的前驱,直接 slow.next = slow.next.next。
中点为何是「快两步、慢一步」:fast 走的路程永远是 slow 的两倍,fast 到终点时 slow 自然在一半处。偶数个节点有两个「中间」,落在哪个全看循环条件:while (fast && fast.next) → slow 停靠后的那个中点;while (fast.next && fast.next.next)
→ 停靠前的。找中点是归并排序链表、判回文链表的第一步。