题目描述
题目: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;
}
};