放一只一步走1格的乌龟和一只一步走2格的兔子到链表的入口. 如果链表不是环形的, 兔子会率先碰到null节点, 反之, 则兔子和乌龟必然会相遇. 设环入口前面的节点数是m, 环长是n, 则乌龟和兔子相遇于时间t, 当且仅当t>m且(2t+1-m)%n=(t+1-m)%n, 这等价于t>m且t%n=0. 也就是说, 自它们第一次相遇后, 任意相邻两次相遇的时间间隔即为n. 观测龟兔, 根据上述判断即可解决问题.
代码:
cpp
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
if(head==nullptr) return nullptr;
ListNode * turtle=head;
ListNode * rabbit=head;
int n=0;
while(true)
{
turtle = turtle->next;
if(rabbit->next!=nullptr) rabbit = rabbit->next;
else return nullptr;
if(rabbit->next!=nullptr) rabbit = rabbit->next ;
else return nullptr;
if(turtle==rabbit) break;
}
while(true)
{
turtle = turtle->next;
rabbit = rabbit->next->next;
n++;
if(turtle==rabbit) break;
}
ListNode * turtle1=head;
ListNode * turtle2=head;
for(int i=0; ; i++)
{
turtle1=turtle1->next;
if(i>=n) turtle2=turtle2->next;
if(turtle1==turtle2) break;
}
return turtle1;
}
};