4
4
import com .rampatra .base .SingleLinkedNode ;
5
5
6
6
/**
7
- * Created by IntelliJ IDEA.
7
+ * See this <a href="https://stackoverflow.com/a/32190575/1385441">Stackoverflow post</a> to understand
8
+ * how to find the starting node of the loop.
9
+ * <p>
10
+ * Proof for Flyod's Loop Detection Algorithm:
11
+ * <p>
12
+ * Suppose fastRunner had just skipped over slowRunner. fastRunner would only be 1 node ahead of slowRunner, since their
13
+ * speeds differ by only 1. So we would have something like this:
14
+ * <p>
15
+ * [ ] -> [s] -> [f]
16
+ * <p>
17
+ * What would the step right before this "skipping step" look like? fastRunner would be 2 nodes back, and slowRunner
18
+ * would be 1 node back. But wait, that means they would be at the same node! So fastRunner didn't skip over slowRunner!
19
+ * (This is a proof by contradiction.)
8
20
*
9
21
* @author rampatra
10
22
* @since 7/1/15
11
- * @time: 12:39 PM
12
23
*/
13
24
public class DetectAndRemoveLoop {
14
25
15
26
/**
16
- * Detects loop if any in {@param list} and removes it.
17
- * <p>
18
- * Algorithm:
27
+ * Detects loop, if any, in {@code list} and removes it.
19
28
* <p>
29
+ * Approach:
20
30
* 1) Use Floyd's cycle detection algorithm to detect loop.
21
31
* 2) Acc. to FCD, once the fast pointer meets the slow pointer we conclude that there is a loop.
22
- * 3 ) Now compute the length 'l' of the loop.
23
- * 4) Move the fast pointer length 'l' from head.
24
- * 5) Now move both slow and fast pointer at same pace and where they meet is the starting point of the loop.
25
- * 6) Lastly, to remove the loop make the next of the node (before the starting point of loop) to null.
32
+ * 4 ) Now that we have concluded there is a loop, let's detect the starting node and remove the loop:
33
+ * i. Move the slow pointer to head.
34
+ * ii. Now, move both slow and fast pointer at same pace and where they meet is the starting point of the loop.
35
+ * iii. Lastly, to remove the loop make the next of the node (before the starting point of loop) to null.
26
36
*
27
37
* @param list
28
38
* @param <E>
29
39
* @return {@code true} if loop exists {@code false} otherwise.
30
40
*/
31
41
public static <E extends Comparable <E >> boolean detectAndRemoveLoop (SingleLinkedList <E > list ) {
32
- int i = 0 , length = 0 ;
33
42
boolean isLoopPresent = false ;
34
- SingleLinkedNode <E > slow = list .head , fast = slow . next ;
43
+ SingleLinkedNode <E > slow = list .head , fast = list . head ;
35
44
36
45
while (fast != null && fast .next != null ) {
46
+ slow = slow .next ;
47
+ fast = fast .next .next ;
37
48
if (slow == fast ) {
38
49
isLoopPresent = true ;
39
50
break ;
40
51
}
41
- slow = slow .next ;
42
- fast = fast .next .next ;
43
52
}
44
53
45
- if (isLoopPresent == false ) return false ;
46
-
47
- // compute length of loop
48
- while (fast .next != slow ) {
49
- fast = fast .next ;
50
- length ++;
51
- }
52
-
53
- // move fast pointer from head by the length of loop
54
- slow = fast = list .head ;
55
- while (i <= length ) {
56
- fast = fast .next ;
57
- i ++;
58
- }
54
+ if (!isLoopPresent ) return false ;
59
55
56
+ slow = list .head ;
60
57
// move both pointers at same pace to determine the starting node of loop
61
58
while (true ) {
62
59
slow = slow .next ;
@@ -72,14 +69,14 @@ public static <E extends Comparable<E>> boolean detectAndRemoveLoop(SingleLinked
72
69
73
70
public static void main (String [] args ) {
74
71
SingleLinkedList <Integer > linkedList = new SingleLinkedList <>();
75
- linkedList .add (00 );
76
- linkedList .add (11 );
77
- linkedList .add (22 );
78
- linkedList .add (33 );
79
- linkedList .add (44 );
80
- linkedList .add (55 );
81
- linkedList .getNode (1 ).next = linkedList .getNode (0 );
72
+ linkedList .add (0 );
73
+ linkedList .add (1 );
74
+ linkedList .add (2 );
75
+ linkedList .add (3 );
76
+ linkedList .add (4 );
77
+ linkedList .add (5 );
78
+ linkedList .getNode (4 ).next = linkedList .getNode (2 );
82
79
System .out .println (detectAndRemoveLoop (linkedList ));
83
80
linkedList .printList ();
84
81
}
85
- }
82
+ }
0 commit comments