【算法】
这个完全是通过数学推导出来的,设一快、一慢两个指针,快指针的步长为2,慢指针为1,假设链表起点到环入口点之间的距离为x,环入口点到重合点的距离为y,假设在相遇之前慢指针走的s,则快指针必然走2s,所以有如下公式:
- s = x + y
- 2s = nr + s(假设环的周长为r,在相遇前快指针走了n圈)
由公式2推导出s = nr,带入公式1得到nr = x + y ===> x = nr -y;
现在再设两个指针p1、p2,步长均为1,p1从单链表起点开始遍历,p2从相遇点开始遍历(相遇点可以得到),根据公式x=nr-y,当p1移动x步时(移动到了入口处),p2移动了nr-y步,由于p2是从相遇点开始遍历的,故nr表示又回到了相遇点,-y表示倒退y步(表示入口点到相遇点的距离),由此可以得到p1和p2是同时到达入口点的。
故算法可以写为:
node* findEntry(node* head, node* encounter)
{
node* p1 = head;
node* p2 = encounter;
while(p1 != p2)
{
p1 = p1->next;
p2 = p2->next;
}
return p1;
}