题目描述:
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始) 如果 pos 是 -1,则在该链表中没有环
说明:不允许修改给定的链表
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:tail connects to node index 1
解释:链表中有一个环,其尾部连接到第二个节点

示例 2:
输入:head = [1,2], pos = 0
输出:tail connects to node index 0
解释:链表中有一个环,其尾部连接到第一个节点

示例 3:
输入:head = [1], pos = -1
输出:no cycle
解释:链表中没有环

/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
思路分析:
<1>第一步先判断链表是否带环,不带环直接返回NULL
<2>如果有环,创建快慢指针,快指针追上慢指针的位置记为相遇点pMeet
<3>创建一个新指针pHead从头部开始和pMeet同时走(每次走一步)
<4>pHead和pMeet相遇的位置就是入环点,返回pHead或者pMeet都行
代码实现:
struct ListNode *detectCycle(struct ListNode *head)
{
//判断链表是否带环
if(head==NULL || head->next==NULL)
{
return NULL;
}
struct ListNode * pFast=head;
struct ListNode * pSlow=head;
while(pFast!=NULL && pFast->next!=NULL)
{
pFast=pFast->next->next;
pSlow=pSlow->next;
if(pFast==pSlow)
{
break;
}
}
if(pFast!=pSlow)
{
return NULL;
}
//从头部和相遇点一起同时走,相遇时,指针指向的位置就是入环点
struct ListNode *pMeet=pFast;
struct ListNode *pHead=head;
while(pHead!=pMeet)
{
pHead=pHead->next;
pMeet=pMeet->next;
}
if(pHead!=pMeet)
{
return NULL;
}
return pMeet;
}
本文介绍了一种高效的链表环检测算法,通过快慢指针判断链表是否存在环,并找到环的入口节点。首先,使用快慢指针判断链表是否带环;若有环,再从头结点和相遇点同时出发,再次相遇即为入环点。

1173

被折叠的 条评论
为什么被折叠?



