标签:
仍然使用龟兔赛跑方法,但还需要在这之上根据证明推倒算法:
不难证明:两指针第一次相遇的地方位于“当慢指针进入环时,快环相对于环起始点的位置”的相反位。例如:
假设一开始Fast和Slow从开始位置开始遍历这个链表。
令m = 3,表示经过三步,Slow结点到达环的起始位置,此时Fast在环的第m个位置,因为Fast比Slow多走了m步
根据刚才的结论,当Slow停在起始位置,Fast停在m位置,两个链表最后会在n-m位置相遇
此时把Slow移到头结点位置,两个结点都是要经过m步,才刚刚好到达环的起始位置。
所以根据这个结论可以写以下算法:
ListNode *detectCycle(ListNode *head) {
if(head == NULL || head->next==NULL || head->next->next==NULL) return NULL;
ListNode* p=head;
ListNode* q=head;
while(1) {
if(p->next == NULL) return NULL;
p = p->next;
q = q->next;
if(p->next != NULL) {
p = p->next;
if(p == q) {
break;
}
}
}
q = head;
while(q!=p) {
p = p->next;
q = q->next;
}
return q;
}
标签:
原文地址:http://www.cnblogs.com/xdlyy/p/5402278.html