LeetCode 142. Linked List Cycle II

141的进阶版,不仅要判断是否存在cycle,还有找出cycle的起始节点。

首先如141所做,根据fast==slow判断是否存在cycle。

如果fast==slow,则slow重置为head,此时fast和slow都每次走一步,当两者相遇时,相遇点即为圆环开头。现在证明为什么slow重置为head后可以一次走到圆环起点。

设非圆环部分有i个节点(不包括和圆环的交点),圆环有j个节点(包括和非圆环的交点)。首先在检测是否存在圆环部分里面,i次循环后,slow到了交点处,位置为i,而此时fast走过了2i个节点(即fast之前有2i个节点),fast在整个链表中位置为2i。现在设交点在圆环中的位置为0,所以slow在圆环中的位置为0,而fast之前的(包括交点这个节点)圆环节点有2i-i=i个,因此fast在圆环中的位置为i。像在141中的解释中一样,x=0,y=i,这样一来解得n=(c-a)j-i,b=x+n-aj=(c-2a)j-i。b为fast的圆环位置,现在slow重置为head,i次后slow到达交点处,而fast的位置为b+i,也就是(c-2a)j,即(c-2a)j%j,等于0,就是交点处。

 

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     ListNode *detectCycle(ListNode *head) {
12         ListNode* slow = head, * fast = head;
13         while(fast && fast->next && fast->next->next){
14             slow = slow->next;
15             fast = fast->next->next;
16             if(slow == fast){//cycle exists
17                 slow = head;
18                 while(slow != fast){
19                     slow = slow->next;
20                     fast = fast->next;
21                 }
22                 return fast;
23             }
24         }
25         
26         return NULL;
27     }
28 };

 

posted @ 2016-04-04 15:22  co0oder  阅读(142)  评论(0编辑  收藏  举报