给定一个头结点为 head 的非空单链表,返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
常规方法也是先遍历链表计算 n,再遍历一次得到第 n / 2 个节点,也就是中间节点。
public ListNode middleNode(ListNode head) {int n = 0;ListNode cur = head;while (cur != null) {++n;cur = cur.next;}int k = 0;cur = head;while (k < n / 2) {++k;cur = cur.next;}return cur;}
如果想一次遍历就得到中间节点,需要使用「快慢指针」的技巧:
让两个指针 slow 和 fast 分别指向链表头结点 head。
每当慢指针 slow 前进一步,快指针 fast 就前进两步,这样,当 fast 走到链表末尾时,slow 就指向了链表中点。
当链表的结点数量是偶数时:
当 fast 指针走到 null 时,slow 走到了中间靠右的结点
当链表的结点数量是奇数时:
当 fast 指针走到的结点的下一个结点是 null 时,slow 走到了中间的结点
public ListNode middleNode(ListNode head) {// 快慢指针都指向头结点ListNode fast = head;ListNode slow = head;// 快指针走到末尾时停止while(fast != null && fast.next != null) {// 慢指针走一步,快指针走两步slow = slow.next;fast = fast.next.next;}// 慢指针指向中点return slow;}
