给你单链表的头结点 head
,请你找出并返回链表的中间结点 Leetcode:链表的中间节点。
如果有两个中间结点,则返回第二个中间结点。
示例 1:
输入:head = [1,2,3,4,5] 输出:[3,4,5] 解释:链表只有一个中间结点,值为 3 。
示例 2:
输入:head = [1,2,3,4,5,6] 输出:[4,5,6] 解释:该链表有两个中间结点,值分别为 3 和 4 ,返回第二个结点。
提示:
- 链表的结点数范围是
[1, 100]
1 <= Node.val <= 100
算法思路其实很简单,定义两个整型变量,count用于计数--统计改链表共有多少个节点,统计完后,再用指针变量Cur进行链表的遍历,同时定义一个整型变量index,当遍历过程中满足:
这个时候返回现在的指针即可!思路如图:
算法代码实现如下:
SListNode* middleNode(SListNode* phead){
if (phead == NULL || phead->next == NULL){
return phead;
}
int count = 0;
int index = 0;
SListNode* Cur = phead;
while(Cur)
{
count++;
Cur = Cur->next;
};
int mid = count/2+1;
Cur = phead;
while(Cur)
{
index++;
if(index == mid){
return Cur;
}
Cur = Cur->next;
};
return NULL;
}
好了,这是一个非常简单的思路。
第二种思路: 快慢指针法:我们利用两个指针,一个指针走的快,一次走两步,一个指针走的慢,一次走一步(停止条件:当我的第一个指针指向为null, 或者第一个指针为null 停止),比如我的链表有2n个元素,当我的第一个指针走到底,共走了n步,而第二个指针走了n步,指向的为第n+1节点,也就是我们的中间的第二个节点,当总共有2n-1个元素时,我的第一个指针只走了n-1步,此时我的第二个指针指向第n个节点正好时中间的值。
思路如图
算法代码实现如下:
SListNode* middleNode(SListNode* phead){
if(phead == NULL || phead->next == NULL){
return phead;
}
SListNode* Fast = phead;
SListNode* Slow = phead;
while (Fast && Fast->next)
{
Slow = Slow->next;
Fast = (Fast->next)->next;
}
return Slow;
}
好了,关于链表的遍历,双指针的思想(快慢指针)思想非常重要,希望大家牢记!