使用快慢指针slow和fast,如果有环,slow和fast必然相遇。设此时slow指针走了x步,环的长度为y,链表总长度位L。
则 2x = x + ny,即快指针已经围绕环转了n圈。
设表头距离环开始位置的距离位t,环开始位置距离相遇位置a,则a+t = x。
x = ny =>
x = (n-1)y + y, =>
a + t = (n-1)y + y, =>
t = (n-1)y + (y-a).
当fast和slow相遇时,使用另外一个指针slow2从head开始走,slow指针从相遇处开始走,两个指针必然在环的开始出相遇。
代码如下。
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode *slow = head, *fast = head;
while(fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
if(fast == slow)
{
ListNode *slow2 = head;
while(slow2 != slow)
{
slow2 = slow2->next;
slow = slow->next;
}
return slow2;
}
}
return NULL;
}
};