Given a linked list, return the node where the cycle begins. If there is no cycle, return null
.
Follow up:
Can you solve it without using extra space?
找出单链表中的环的起点,最初用的标记的办法,但是不符合题意,最后参阅了网上资料,深感自己智商不足啊
class Solution {
public:
ListNode * getMeetPlace(ListNode *head){
if(head==NULL) return NULL;
ListNode * fast = head, * slow = head;
do{
if(fast==NULL || fast->next==NULL) return NULL;
fast = fast->next->next;
slow = slow->next;
}while(fast!=slow);
return fast;
}
ListNode *detectCycle(ListNode *head) {
ListNode * p1 = getMeetPlace(head);
if(p1==NULL) return NULL;
ListNode * p2 = head;
while(p1!=p2){
p1 = p1->next;
p2 = p2->next;
}
return p1;
}
};
原理很简单,设 慢指针到达环起点路程为x,两指针相遇后慢指针走过路程为y ,环的长度为r,链表总长度为L
则:
x + y = 2(x+y) + nr
x + y = nr =(n-1)r + L -x
x = (n-1)r + L - x - y
L-x-y 为环相遇点离环入口长度
那么在相遇点和链表起点各设指针向后移动,则他们会在环入口处相遇