/**
 * 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;  
}

图解: