链表的中间结点
题目描述:
给你单链表的头结点 head ,请你找出并返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
题目链接:https://leetcode.cn/problems/middle-of-the-linked-list/description/
解题思路
思路一:
要找中间节点我们可以先把链表所有节点数出来后再找中间节点,这也是常规思路。
思路二:
快慢指针法——这个才是我最推荐的(推荐推荐再推荐!!!)
定义一个块指针和慢指针先指向头节点,让快指针每次走两步,慢指针每次走一步,当快指针走到最后一个节点(节点总数为偶数个)或者快指针走完所有节点(节点总数为奇数个)时,慢指针的位置刚好就是中间节点的位置。
解法图示
思路一:
思路二:
示例代码:
解法一:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode LN;
struct ListNode* middleNode(struct ListNode* head) {
//解法二:先遍历所有链表数出链表节点数量,再找中间节点
if(head==NULL)
{
return NULL;
}
int count=0,i;
LN* cur=head;
//遍历链表数出链表的所有节点数
while(cur)
{
cur=cur->next;
count++;
}
cur=head;
i=count/2;//count/2表示链表要从头节点指向中间节点向后移的次数
//从头节点移到中间节点处
while(i--)
{
cur=cur->next;
}
return cur;
}
解法二:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode LN;
struct ListNode* middleNode(struct ListNode* head) {
//解法一:快慢指针法
//头节点是否为空?
if(head==NULL)
{
return NULL;
}
//定义快慢指针指向头
LN* slow,*fast;
slow=fast=head;
//慢指针一次走一步,快指针一次走两步
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
}
//走完后慢指针处就是中间节点位置
return slow;
}
代码一览:
补充:
注意在上面的快慢指针的代码中的循环条件里,“&&”两侧表达式位置不能交换,如: