力扣Leet Code刷题笔记(四)–876.链表的中间节点
这是我的刷题笔记第四篇,这篇主要使用了快慢指针的方法来找到链表的中间节点。
前言
这篇文章使用c语言进行实现
我们开始吧
点此直达哦->876.链表的中间节点
题目描述
给你单链表的头结点head
,请你找出并返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
示例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
解题思路
本题我想到了两种解决方法:
- 遍历
- 快慢指针
方法一: 遍历链表
思路: 假想链表下标为0 1 2 3… n-1,我们可以遍历链表,当遍历到第n/2个节点时,我们就找到了链表的中间节点。
注意这边当中间节点为2个时是要找到第二个中间节点
比如:
- 示例一中有五个节点 5/2 = 2, 找到下标为2的节点地址
- 示例二中有六个节点 6/2 = 3, 找到下标为3的节点地址,的确是第二个中间节点
Code 代码:
// 这个代码比较简单,就不做演示了,大家感兴趣可以自己试试
很明显,这种遍历的方法效率是非常低下的,在遍历完一遍之后还要再遍历找到中间节点,
那么有没有什么办法可以实现在遍历的过程中就找到中间节点呢?
方法二: 快慢指针
快慢指针就是一个不错的办法,我们可以设置两个指针,一个指针slow
每次移动一步,另一个指针fast
每次移动两步,他们的步长差为1,在fast
遍历完整个链表的时候,slow
就是这个链表的中间节点
快指针的->next是NULL 或者 快指针是NULL,就是到达了链表的末尾
这样可以在链表元素个数为偶数的时候,找到第二个中间节点
如果是要找到第一个中间节点,可以是快指针->next->next是NULL或者快指针->
next是NULL,就是到达链表的末尾
这样可以在链表元素个数为奇数的时候,找到第一个中间节点
Code 代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode ListNode;
// 双指针:快慢指针
// 分析: 以0 1 2 3... 作为下标 中间节点为 节点数/2
struct ListNode* middleNode(struct ListNode* head)
{
ListNode* pslow = head;
ListNode* pfast = head;
// 偶数链表需要找到第二个中间节点
while (pfast != NULL && pfast->next != NULL)
{
pslow = pslow->next;
pfast = pfast->next->next;
}
return pslow;
}
心得 thought bubbles
这道题的思想是使用快慢指针的步长差进行遍历
种种思想在很多其他题上面都可以用到,其他地方的步长差会是其他大小的数字,但依旧是快慢指针
😄