1. 题目描述

给定一个头结点为 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。

示例 1:

  1. 输入:[1,2,3,4,5]
  2. 输出:此列表中的结点 3 (序列化形式:[3,4,5])
  3. 返回的结点值为 3 (测评系统对该结点序列化表述是 [3,4,5])。
  4. 注意,我们返回了一个 ListNode 类型的对象 ans,这样:
  5. ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.next = NULL.

示例 2:

  1. 输入:[1,2,3,4,5,6]
  2. 输出:此列表中的结点 4 (序列化形式:[4,5,6])
  3. 由于该列表有两个中间结点,值分别为 3 4,我们返回第二个结点。

提示:

  • 给定链表的结点数介于 1100 之间。

    2. 解题思路

    对于这种求链表的中间点的题,我们可以使用快慢指针来实现,初始化slow和fast两个指针,开始时两个指针都指向头结点。然后慢指针一次走一步,快指针一次走两步,这样快指针走完整个链表时,慢指针正好走到链表的中间。

在遍历的过程中,如果快指针的后一个节点为空,就结束遍历,返回慢指针的值。

复杂度分析:

  • 时间复杂度:O(n),其中 n 是给定链表的结点数目。
  • 空间复杂度:O(1),只需要常数空间来存放 slowfast 两个指针。

    3. 代码实现

    1. /**
    2. * Definition for singly-linked list.
    3. * function ListNode(val) {
    4. * this.val = val;
    5. * this.next = null;
    6. * }
    7. */
    8. /**
    9. * @param {ListNode} head
    10. * @return {ListNode}
    11. */
    12. var middleNode = function(head) {
    13. let fast = head, slow = head
    14. while(fast && fast.next){
    15. slow = slow.next
    16. fast = fast.next.next
    17. }
    18. return slow
    19. };

    4. 提交结果

    image.png