这一篇博客继续在算法题的海洋里面遨游~
链表的中间结点
链表的中间结点:
https://leetcode.cn/problems/middle-of-the-linked-list/description/
这个题我们可以怎么办呢?这里依然提供两个思路
思路1
既然是中间结点我们是不是可以直接第一次循环求链表结点的总个数,除2就可以得到中间位置,再一次循环找到中间位置结点,这一个思路就需要两个循环实现。
代码实现:
typedef struct ListNode ListNode;
struct ListNode* middleNode(struct ListNode* head)
{
//第一次循环遍历知道结点总个数
int longList = 0;
ListNode* pcur1 = head;
while (pcur1)
{
longList++;
pcur1 = pcur1->next;
}
//找到中间结点
//例:(结合题目中间结点的概念)
// 总个数:5 奇数 mid = 2
// 总个数:6 奇数 mid = 3
int mid = longList / 2;
//这里mid代表往后面走几次到中间结点
//类似下标理解
//第二次循环找到并且返回中间结点
ListNode* pcur2 = head;
while (mid--)
{
pcur2 = pcur2->next;
}
//返回中间结点
return pcur2;
}
成功通过,这里使用了两次循环,有没有只需要使用一次循环的方法呢?也就是我们的思路2
思路2
快慢指针法
定义两个指针slow=fast=head,一个是快指针fast每次走两步,一个是慢指针slow每次走一步,当fast为NULL(偶数)fast->next为NULL(奇数)时,循环结束,返回慢指针。
原理:2*慢指针==快指针
画图理解:
代码实现:
//2.快慢指针
typedef struct ListNode ListNode;
struct ListNode* middleNode(struct ListNode* head)
{
//创建两个指针
ListNode* slow, * fast;
slow = fast = head;
while (fast && fast->next)
//顺序不可以换,避免空指针解引用
//&&会有短路现象(如果&&左边表达式成立,右边就不会执行运算)
{
//慢指针走一步
slow = slow->next;
//快指针走两步
fast = fast->next->next;
}
//返回慢指针
return slow;
}
成功通过,这里代码也就更加简便,是不是十分巧妙~~~
今日练习结束,期待与各位未来的优秀程序员交流,有什么问题请私信~~~