给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
不允许修改 链表。
输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。
思路1:
首先,判断链表是否有环,使用快慢指针来判断,如果有环,找到快慢指针相遇的结点
其次,如果有环,定义两个指针,分别从链表头结点cur和快慢指针相遇的结点meet开始走,两个指针每次都走一步,那么这两个指针必然在入环第一个结点处相遇。
struct ListNode* detectCycle(struct ListNode* head)
{
//1.判断是否带环
//使用快慢指针,如果带环,找到快慢指针的相遇点
struct ListNode* slow = head;
struct ListNode* fast = head;
while (fast != NULL && fast->next != NULL)
{
slow = slow->next;
fast = fast->next->next;
if (fast == slow)
{
//带环,相遇
struct ListNode* meet = slow;
//2.一个从链表头结点开始走,一个从相遇点开始走,两个指针每次都走一步
struct ListNode* cur = head;
while (cur != meet)
{
cur = cur->next;
meet = meet->next;
}
//相遇点就是入环结点
return meet;
}
}
//不带环
return NULL;
}
思路2:
把快慢指针的相遇点置为NULL,从相遇点的下一个结点开始,找到和原链表的第一个相交结点,这样就转换成链表相交结点的问题。(也可以不破坏原链表结构,快慢指针的相遇结点作为尾结点,相遇结点的下一个结点作为头结点,找到这个新链表与原链表的第一个交点)