【力扣算法题】找链表中间节点
题目介绍
给定一个头结点为 head 的非空单链表,返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点
题解
1. 快慢指针(个人解法/力扣官方解法3)
看到题目我就笑了,直接快慢指针
快慢指针本身常常用于找链表是否有环,但对于这题也刚好适用,因为快指针的移速刚好是慢指针的两倍,那么快指针到头时,慢指针刚好指在中间的位置
C++源码:
ListNode* middleNode(ListNode* head) {
ListNode* slowNode = head;
ListNode* fastNode = head;
int counter = 2;
while(fastNode->next != nullptr)
{
if(counter > 1)
{
counter = 0;
slowNode = slowNode->next;
}
fastNode = fastNode->next;
counter++;
}
return slowNode;
}
2. 超暴力数组(力扣官方解法1)
道理简单,直接开个数组(要求至少是支持扩容的动态数组,C++的普通数组肯定是不行的)
把链表的元素全赛到数组里,之后利用数组索引的优势,直接取得中间的节点
C++源码:
ListNode* middleNode(ListNode* head) {
vector<ListNode*> A = {head};
while (A.back()->next != NULL)
A.push_back(A.back()->next);
return A[A.size() / 2];
}
// 作者:LeetCode-Solution
// 链接:https://leetcode-cn.com/problems/middle-of-the-linked-list/solution/lian-biao-de-zhong-jian-jie-dian-by-leetcode-solut/
3. 单指针(力扣官方解法2)
先遍历一次链表,记录一下长度,之后第二次遍历的时候,用之前的长度作为参考,到一般的时候停下来,就获得了中间节点
C++源码:
ListNode* middleNode(ListNode* head) {
int n = 0;
ListNode* cur = head;
while (cur != nullptr) {
++n;
cur = cur->next;
}
int k = 0;
cur = head;
while (k < n / 2) {
++k;
cur = cur->next;
}
return cur;
}
// 作者:LeetCode-Solution
// 链接:https://leetcode-cn.com/problems/middle-of-the-linked-list/solution/lian-biao-de-zhong-jian-jie-dian-by-leetcode-solut/