题目描述
给定一个带有头结点 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,我们返回第二个结点。
使用语言:C语言
思路解析
看到题目最先想到的思路就是遍历一遍链表得到链表的节点数sum,然后让一个指针从头开始走(sum/2)步就可以找到中间节点了,这么做相当于将链表遍历了一遍半,我们使用一个只遍历一遍链表的方法:
- 创建两个指针fast、slow,分别为快慢指针
- fast指针每次走两步,slow指针每次走一步,当fast指针走到链表末尾的时候,slow指针就在链表中间了
- 实现这个算法的关键在于如何给while循环条件,能保证fast指针每次都能走两步。第一个条件fast != NULL,这是保证fast指针走第一步,第二个条件fast->next != NULL,这是保证fast指针走第二步
代码实现
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode Node;
struct ListNode* middleNode(struct ListNode* head){
Node* fast=head;
Node* slow=head;
while(fast && fast->next)
{
fast=fast->next->next;
slow=slow->next;
}
return slow;
}
运行结果