快慢指针,顾名思义就是设置两个指针,在同一个链表中不同步的游走。快指针每次走两步,慢指针每次走一步,如果链表不是循环链表,那么快指针会始终在慢指针前面,如果链表存在环路,那么当进入环中以后,由于快指针移动较快,它与慢指针总会有相遇的时刻。就如同我们在环形跑道上跑步一样,速度快的人在跑若干圈之后会再次追上速度慢的人,再次相遇。因此本节我们介绍如何利用快慢指针来判断一个链表是否存在环并返回环开始的结点。
从上面的分析我们知道要判断是否存在环是比较容易的,那么如何找到并返回环开始的结点呢,具体请看这篇文章的数学推导(参考),那么最终的结论是:当快慢指针第一次在环内的某一结点处相遇时,令其中一个指针指向链表的头结点,然后二者同步移动,每次都只移动一步,最终再次相遇的地方即为环的开始结点。
node* loopStart(node* head)
{
if(!head)
return NULL;
node* slow = head;
node* fast = head;
while(fast && fast->next)
{
fast = fast->next->next;
slow = slow->next;
if(fast == slow)
break;
}
if(!fast || !fast->next)
return NULL;
fast = head;
while(fast != slow)
{
fast = fast->next;
slow = slow->next;
}
return fast;
}