✨题目
给定一个头结点为 head 的非空单链表,返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
✨样例
示例 1: 输入:[1,2,3,4,5] 输出:此列表中的结点 3 (序列化形式:[3,4,5])
示例2: 输入:[1,2,3,4,5,6] 输出:此列表中的结点 4 (序列化形式:[4,5,6])
✨提示
- 给定链表的结点数介于 1 和 100 之间。
👍解题
方法一:利用数组
链表和数组相比来说,不好求中间节点的原因在于我们没办法直接按照 长度 / 2 的方式,来得到中间的节点,所以我们不妨遍历整个链表,然后把所有节点都添加到 vector 中。然后直接返回 vector[ vector.size( ) / 2]就可以了
/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/class Solution {public:ListNode* middleNode(ListNode* head) {vector<ListNode*> arr;while(head != NULL){arr.push_back(head); // 把所有的节点添加到vector中head = head->next;}int len = arr.size();return arr[len / 2];}};
方法二:单指针
上面说到,链表和数组相比来说,不好求中间节点的原因在于我们没办法直接按照 **长度 / 2** 的方式,来得到中间的节点,那我们不妨遍历一次链表,然后求出链表的长度,然后遍历的时候只遍历链表的一半长度即可。
/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/class Solution {public:ListNode* middleNode(ListNode* head) {ListNode* node = head;int sum = 0;int temp = 0;while(node != NULL){sum ++;node = node->next;}while(temp < sum / 2){head = head->next;temp ++;}return head;}};
方法三:快慢指针
不妨设置两个指针同时来遍历链表,其中一个快指针的步长为2,慢指针的步长为1,这样的话,当快指针遍历到末尾的时候,慢指针一定是在链表的中间。
/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/class Solution {public:ListNode* middleNode(ListNode* head) {ListNode* high = head;ListNode* low = head;while(high != NULL && high->next != NULL){high = high->next->next;low = low->next;}return low;}};
