基础算法(二)找出单向链表中环的入口
这里假设:
a是头结点到环的入口的距离
b是环入口到相遇结点的距离
c是整个环的长度
一般来说,两个指针相遇的时候,慢指针还没走完一圈,但此时快指针已经走完一圈多了。
计算快慢指针所走过的距离:
dis(fast) = a + b +c
dis(slow) = a + b
又已知 快指针 比 慢指针 快两倍,因此快指针走过的路程为慢指针的两倍。
dis(fast) = dis(slow)*2
化简后得:
a = c - b
用环的长度 减去 慢指针走过的距离,就是头结点到环入口的距离了。
这意味着在第一次相遇后,将快指针重新从开始,每次一步,下次快慢指针再相遇就是环入口处了。
以下为实现的代码:
struct ListNode* detectCycle(struct ListNode* head ) {
// write code here
if(head == NULL)
{
return NULL;
}
else
{
struct ListNode*fast = head;
struct ListNode*slow = head;
//先判断是否有环链表,如果不是就返回NULL
while(fast != NULL && fast->next != NULL)
{
fast = fast->next->next;
slow = slow->next;
if(slow == fast)//如果快慢指针能相遇证明是有环链表
{
fast = head; //让 快指针 回到头结点
while(fast != slow)
{ //俩个指针继续一步一步往前走,直到相遇
fast = fast->next;
slow = slow->next;
}
return fast; //把环的入口返回出去
}
}
return NULL;
}
}