找到链表中点

181 阅读1分钟

题目描述

题目:876. 链表的中间结点

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

利用额外空间

把所有节点遍历一遍放入到vector中,根据vector的长度即可知道链表的长度,后续只需返回位于vector.size() / 2位置的节点即可。

class Solution {
public:
    ListNode* middleNode(ListNode* head) {
        vector<ListNode*> lists;

        auto *dummy = head;
        while (dummy != nullptr) lists.push_back(dummy), dummy = dummy->next;

        return lists[lists.size() / 2];
    }
};

统计长度

先遍历一遍链表,统计链表的长度,再遍历cnt / 2次找到位于中间位置的节点,返回即可。

class Solution {
public:
    ListNode* middleNode(ListNode* head) {
        int cnt = 0; auto *dummy = head;
        while (dummy != nullptr) dummy = dummy->next, ++cnt;

        int i = 0; dummy = head;
        while (i < cnt / 2) {
            dummy = dummy->next, ++i;
        }
        return dummy;
    }
};

双指针

采用双指针,slow为慢指针,fast为快指针。每次slow往后移动一步,fast向后移动二步。

fast到达链表尾部的时候,slow指针正好再链表中间位置。

class Solution {
public:
    ListNode* middleNode(ListNode* head) {
        auto *fast = head, *slow = head;

        while (fast != nullptr && fast->next != nullptr) {
            fast = fast->next->next;
            slow = slow ->next;
        }
        return slow;
    }
};