Leetcode#142 Linked List Cycle II

原题地址

 

经典的链表题目。

1. 用双指针法判断是否有环

2. 将一个指针重置为链表首部,另一个指针保留在之前重合的位置,两个指针同时移动,相遇位置即为环出现的位置

2的证明:

设链表头节点是A,环出现位置为B,快慢指针最终相遇位置为C,如下图所示

设环的周长为p,则有:

1. 快指针所走的路径长度为 L_fast = AB + BC + np,其中n是整数

2. 慢指针所走的路径长度为 L_slow = AB + BC,因为慢指针在环里最多走了一圈

3. 因为快指针比慢指针的速度快一倍,所以 L_fast = 2 * L_slow

三式联立,化简得:

AB + BC = np

等价转化:AB = np - BC = (n - 1)p + (p - BC) = (n-1)p + CB

即AB - CB = mp,其中m是整数

所以,让两个指针分别从A和C出发,当其中一个指针走到B的位置时,另一个指针距离B的位置恰好是环长度的整数倍,因此最终他们在换上相遇的位置一定还在B

 

代码:

 1 ListNode *detectCycle(ListNode *head) {
 2         ListNode *fast = head;
 3         ListNode *slow = head;
 4         bool running = false;
 5         
 6         while (fast && fast->next) {
 7             if (fast == slow && running)
 8                 break;
 9             running = true;
10             fast = fast->next->next;
11             slow = slow->next;
12         }
13         
14         if (!fast || !fast->next)
15             return NULL;
16         
17         fast = head;
18         while (fast != slow) {
19             fast = fast->next;
20             slow = slow->next;
21         }
22         
23         return fast;
24 }

 

posted @ 2015-01-28 14:25  李舜阳  阅读(213)  评论(0编辑  收藏  举报