LeetCode: Linked List Cycle II 解题报告

Linked List Cycle II

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?

 

SOLUTION 1:

1. 先用快慢指针判断是不是存在环。

2. 再把slow放回Start处,一起移动,直到二个节点相遇,就是交点。

现在有两个指针,第一个指针,每走一次走一步,第二个指针每走一次走两步,如果他们走了t次之后相遇在K点

那么       指针一  走的路是      t = X + nY + K        ①

             指针二  走的路是     2t = X + mY+ K       ②          m,n为未知数

把等式一代入到等式二中, 有

2X + 2nY + 2K = X + mY+ K

X + (2n-m)Y + K = 0;

X + K = (m - 2n)Y

这就清晰了,X和K的关系是基于Y互补的。等于说,两个指针相遇以后,再往下走X步就回到Cycle的起点了。这就可以有O(n)的实现了。

Ref: http://fisherlei.blogspot.com/2013/11/leetcode-linked-list-cycle-ii-solution.html

解释2:

主页群自己也算了一下,给出另一个解释:

图片来源

假设S,F两个指针首次相遇在Z点,SL, SF分别为两个指针走过的距离,则

SL = a + b

SF = a + b + nL (L 为环的周长)

=> 2(a + b) = a + b + nL

a + b = nL

a = nL - b = (n - 1)L + L - b = (n - 1) L + c

因为a + b > 0,所以nL > 0, n > 0, n >= 1 推出 n - 1 >= 0

所以,a的长度为c 加上 ML  (M > 0)

就是当SLOW重新从原点出发,而FAST继续走时,当SLOW走到Y点,FAST也会绕N圈后再走C长度到达Y点,

两个点正好会在Y点相遇。

得证。

 1 /**
 2  * Definition for singly-linked list.
 3  * class ListNode {
 4  *     int val;
 5  *     ListNode next;
 6  *     ListNode(int x) {
 7  *         val = x;
 8  *         next = null;
 9  *     }
10  * }
11  */
12 public class Solution {
13     public ListNode detectCycle(ListNode head) {
14         if (head == null) {
15             return null;
16         }
17         
18         ListNode s = head;
19         ListNode f = head;
20         
21         ListNode cross = null;
22         
23         while (f != null && f.next != null) {
24             s = s.next;
25             f = f.next.next;
26             
27             if (s == f) {
28                 cross = s;
29                 
30                 // remember to break here, or you will get a loop.
31                 break;
32             }
33         }
34         
35         // don't detect any cycle.
36         if (cross == null) {
37             return null;
38         }
39         
40         // place the slow to the start again.
41         s = head;
42         while (true) {
43             if (s == f) {
44                 return s;
45             }
46             
47             s = s.next;
48             f = f.next;
49         }
50     }
51 }
View Code

 

GITHUB:

https://github.com/yuzhangcmu/LeetCode_algorithm/blob/master/list/DetectCycle.java

 

posted on 2014-12-10 15:58  Yu's Garden  阅读(867)  评论(0编辑  收藏  举报

导航