首先这道题可以分解为两个部分,第一判断是否有环,第二找到环的入口。
首先说判断一个链表是否有环,设置两个指针(慢指针和快指针),其中慢指针每次走一步,快指针一次走两步,若两指针相遇则为有环,否则无环,代码见meeting函数。
第二当有环时,通过meeting函数找到指向相遇的结点的指针meetNode,作为其中一个指针node1的起始位置,另一个指针node2从头节点开始出发,每次两个指针都走向前一步,直到相遇,即slow==fast,该节点即为环的入口节点。
代码如下:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
if(head==nullptr) return nullptr;
ListNode *meetNode=meeting(head);
if(meetNode==nullptr) return nullptr;
ListNode *node1=meetNode;
ListNode *node2=head;
while(node1!=node2)
{
node1=node1->next;
node2=node2->next;
}
return node1;
}
ListNode *meeting(ListNode *head)
{
ListNode *slow=head;
ListNode *fast=head;
while(fast!=nullptr&&fast->next!=nullptr)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast)
return slow;
}
return nullptr;
}
};