给定一个头结点为 head 的非空单链表,返回链表的中间结点。

如果有两个中间结点,则返回第二个中间结点。

 

示例 1:

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

示例 2:

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

 

提示:

  • 给定链表的结点数介于 1 和 100 之间。
Related Topics
  • 链表
  • 双指针

  • 👍 388
  • 👎 0
  • 题解

    直观第一反应就是双指针,一个直接往末尾跑,另一个每当往末尾跑的指针跑了两下的时候,往后跑一下。不过也可以最简单的,从头跑到尾知道有多长了之后再取中间那个,取中间那个可以再从头跑一遍,也可以把跑过的记录存起来记录是第几个,然后直接取对应的中间那个。

    先双指针:

    class Solution {
    
        int curIndex = 1;
    
        public ListNode middleNode(ListNode head) {
            ListNode mid = head;
            ListNode cur = head;
            while (cur.next != null){
                cur = cur.next;
                curIndex = curIndex==2?1:curIndex+1;
                if (curIndex==2){
                    mid = mid.next;
                }
            }
            return mid;
        }
    }

    也可以不用curIndex变量记录。直接在while循环里尝试访问cur.next.next

    class Solution {
    
        public ListNode middleNode(ListNode head) {
            ListNode mid = head;
            ListNode cur = head;
            while (cur.next != null){
                cur = cur.next;
                if (cur.next !=null){
                    cur =cur.next;
                }
                mid = mid.next;
            }
            return mid;
        }
    }

    再写个List集合的

    class Solution {
    
        public ListNode middleNode(ListNode head) {
            if (head==null)return null;
            List<ListNode> list = new ArrayList<>();
            list.add(head);
            while (head.next != null){
                head = head.next;
                list.add(head);
            }
            return list.get(list.size()/2);
        }
    }

    跑了一下看看好像List集合的比双指针的占用内存还小点?还是服务器问题?