/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* @author Senky
* @date 2023.04.15
* @par url https://www.nowcoder.com/creation/manager/content/584337070?type=column&status=-1
* @param pHead ListNode类
* @return ListNode类
*/
struct ListNode* EntryNodeOfLoop(struct ListNode* pHead ) {
// write code here
struct ListNode* slow = pHead;
struct ListNode* fast = pHead;
int IsCycle = 0;
/*
*判断链表有没有环
*/
while(fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
if(slow == fast)
{
IsCycle = 1;
break;
}
}
/*
*链表头到环入口长度为--a
*环入口到相遇点长度为--b
*相遇点到环入口长度为--c
*快指针路程=a+(b+c)k+b ,k>=1(其中b+c为环的长度,k为绕环的圈数)
*慢指针路程=a+b
*快指针走的路程是慢指针的两倍,所以:
*(a+b)*2=a+(b+c)k+b
*即 a = (k-1)(b+c)+c ,说明链表头到环入口的距离 = 相遇点到环入口的距离 +(k-1)环的长度
*也就是说,两个指针分别从链表头和相遇点同时以相同的速度出发,当相遇时相遇点是环入口
*/
if(1 == IsCycle)
{
fast = pHead;
while(slow != fast)
{
slow = slow->next;
fast = fast->next;
}
}
else
{
fast = NULL;
}
return fast;
}
图解:
