链表OJ2——链表的中间结点(c语言实现)

声明:我的链表OJ系列是针对无头单向不循环链表的题目

题目 

题目来源:. - 力扣(LeetCode)

思路1——直接遍历

因为这道题目并没有时间复杂度的规定,所以若想要解决这道问题是非常简单的。我们只需要先遍历一遍链表,统计链表当中的结点个数,然后再遍历一遍链表,寻找中间位置的结点即可。

struct ListNode {
	int val;
	struct ListNode *next;
};

struct ListNode* middleNode(struct ListNode* head)
{
	struct ListNode* cur = head;//记录当前结点位置
	int count = 0;//记录链表中结点的总数
	while (cur)//遍历的停止条件
	{
		count++;//总数加一
		cur = cur->next;//指针后移
	}
	int mid = count / 2;//中间结点与第一个结点之间相差的结点数
	struct ListNode* midnode = head;//记录中间结点的位置
	while (mid--)//从第一个结点开始,指针后移mid个结点
	{
		midnode = midnode->next;//指针后移
	}
	return midnode;//返回中间结点
}

 思路2——快慢指针

既然我们要找的是中间位置的结点,那么我们可以定义两个指针,第一个指针指向当前遍历到的最后一个结点,第二个指针时刻指向已经遍历过的结点的中间结点。如此进行下去,因为第二个指针始终指向的是已经遍历过的结点的中间结点,所以当链表遍历完后直接返回第二个指针即可。这就是所谓的“快慢指针”。

寻找规律:
我们不妨定义两个指针名叫:fast,slow。
fast:记录当前遍历到的最后一个结点。(快指针)
slow:记录已经遍历过的结点的中间结点。(慢指针)

通过观察,我们可以发现,当slow指针走一步时,fast指针走一步或是走两步都满足slow指针指向的是已经遍历过的结点的中间结点。也就是slow指针走一步,fast指针最多可以走两步。

所以,我们可以遍历链表,当fast指针遍历到链表末尾时,就立刻返回此时的slow指针即可。

需要注意的是:因为fast指针一次是走两步,所以当fast指针指向的内容为空或是fast指针指向的结点所指向的内容为空时,均停止遍历链表。

这两种情况下均停止遍历,立刻返回slow指针。

这样,我们就在只遍历了一遍链表的情况下找到了中间结点的位置,即时间复杂度为O(n)。

struct ListNode {
	int val;
	struct ListNode *next;
};

struct ListNode* middleNode(struct ListNode* head)
{
	struct ListNode* fast = head;//快指针
	struct ListNode* slow = head;//慢指针
	while (fast&&fast->next)//遍历继续的条件
	{
		slow = slow->next;//慢指针一次走一步
		fast = fast->next->next;//快指针一次走两步
	}
	return slow;//返回慢指针
}

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值