1.题目
给定一个链表的头节点 head
,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
。
如果链表中有某个节点,可以通过连续跟踪 next
指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos
是 -1
,则在该链表中没有环。注意:pos
不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。原题
2.方法
方法1让一个指针从链表其实位置开始遍历链表,同时让另一个指针从判环相遇点的位置开始绕环运行,两个指针每次都走一步,最终肯定会在入口点的位置相遇。
证明:如图
3.代码
//方法1代码
typedef struct ListNode Node;
struct ListNode *detectCycle(struct ListNode *head)
{
//思路1
//使用快慢指针,让他们入环以后找到它们的相遇点,一个指针从相遇点 开始向后走
//另一个指针从开始向后走
//它们再次相遇时相遇点就是入环的第一个节点
if(head == NULL || head->next == NULL)//如果指针为空直接返回
return NULL;
Node* slow = head;
Node* fast = head;
int flag = 0;
while(fast && fast->next)
{
fast = fast->next->next;
slow = slow->next;
if(fast == slow)
break;//找到快慢指针的相遇点
}
if(slow == NULL)
return NULL;
Node* firstNode = head;
while(slow)
{
if(slow == firstNode)
return slow;//从快慢指针相遇点向后走,从头开始一起向后走,相遇点就是入环的第一个节点
firstNode = firstNode->next;
slow = slow->next;
}
//走到这里说明不存在环直接返回NULL
return NULL;
}