题目描述:
给定一个头结点为 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,我们返回第二个结点。
解题思路:
方法一:
将链表遍历两次,第一次遍历链表计算链表的元素个数count,第二次遍历到count/2个元素(链表的首元素是0)时将其元素返回。
方法二:
将方法一进行优化,设置两个指针,一个快指针,一个慢指针,慢指针一次走一步,快指针一次走两步,当快指针的到达链表的末尾时,慢指针的位置就是中间元素所在位置。
方法三:
链表的缺点在于不能通过下标访问链表元素,我们可以考虑遍历整个链表,将元素放到一个数组A中,如果我们遍历到了N个元素,那么链表长度也为N,链表中间元素为A[N/2],然后将其元素下标返回即可。
代码实现:
方法一:
class Solution {
public:
ListNode* middleNode(ListNode* head) {
ListNodecur=head;
int count=0;
while(cur)
{
count++;
cur=cur->next;
}
int k=0;
cur=head;
while(k<count/2)
{
k++;
cur=cur->next;
}
return cur;
}
};
方法二:
class Solution {
public:
ListNode middleNode(ListNode* head) {
ListNodeslow=head;
ListNodefast=head;
while(fast!=NULL&&fast->next!=NULL)
{
slow=slow->next;
fast=fast->next->next;
}
return slow;
}
};
方法三:
class Solution {
public:
ListNode* middleNode(ListNode* head) {
vector<ListNode*> A = {head};
while (A.back()->next != NULL)
A.push_back(A.back()->next);
return A[A.size() / 2];
}
};
给定一个非空单链表,返回链表的中间节点。如果存在两个中间节点,返回第二个。本文介绍了三种解题方法:双遍历计数、快慢指针和转换为数组定位。

735

被折叠的 条评论
为什么被折叠?



