File tree 3 files changed +97
-0
lines changed
Data-Structures/Linked-List
3 files changed +97
-0
lines changed Original file line number Diff line number Diff line change 82
82
* ** Linked-List**
83
83
* [ AddTwoNumbers] ( Data-Structures/Linked-List/AddTwoNumbers.js )
84
84
* [ CycleDetection] ( Data-Structures/Linked-List/CycleDetection.js )
85
+ * [ CycleDetectionII] ( Data-Structures/Linked-List/CycleDetectionII.js )
85
86
* [ DoublyLinkedList] ( Data-Structures/Linked-List/DoublyLinkedList.js )
86
87
* [ MergeTwoSortedLinkedLists] ( Data-Structures/Linked-List/MergeTwoSortedLinkedLists.js )
87
88
* [ ReverseSinglyLinkedList] ( Data-Structures/Linked-List/ReverseSinglyLinkedList.js )
Original file line number Diff line number Diff line change
1
+ /**
2
+ * A LinkedList based solution for finding the starting node of the cycle in a list.
3
+ * @returns the node where cycle begins in the linked list. If there is no cycle present, returns null.
4
+ * @see https://en.wikipedia.org/wiki/Cycle_detection
5
+ * @see https://leetcode.com/problems/linked-list-cycle-ii/
6
+ */
7
+
8
+ function findCycleStart ( head ) {
9
+ let length = 0
10
+ let fast = head
11
+ let slow = head
12
+
13
+ while ( fast !== null && fast . next !== null ) {
14
+ fast = fast . next . next
15
+ slow = slow . next
16
+ if ( fast === slow ) {
17
+ length = cycleLength ( slow )
18
+ break
19
+ }
20
+ }
21
+
22
+ if ( length === 0 ) {
23
+ // If there is no cycle, return null.
24
+ return null
25
+ }
26
+
27
+ let ahead = head
28
+ let behind = head
29
+ // Move slow pointer ahead 'length' of cycle times
30
+ while ( length > 0 ) {
31
+ ahead = ahead . next
32
+ length --
33
+ }
34
+
35
+ // Now move both pointers until they meet - this will be the start of cycle
36
+ while ( ahead !== behind ) {
37
+ ahead = ahead . next
38
+ behind = behind . next
39
+ }
40
+
41
+ // return the meeting node
42
+ return ahead
43
+ }
44
+
45
+ // head is a node on a cycle
46
+ function cycleLength ( head ) {
47
+ // How long until we visit head again?
48
+ let cur = head
49
+ let len = 0
50
+ do {
51
+ cur = cur . next
52
+ len ++
53
+ } while ( cur != head )
54
+ return len
55
+ }
56
+
57
+ export { findCycleStart }
Original file line number Diff line number Diff line change
1
+ import { findCycleStart } from '../CycleDetectionII'
2
+ import { Node } from '../SinglyLinkedList'
3
+
4
+ describe ( 'Detect Cycle' , ( ) => {
5
+ it ( 'no cycle' , ( ) => {
6
+ const head = new Node ( 1 )
7
+ head . next = new Node ( 2 )
8
+
9
+ expect ( findCycleStart ( head ) ) . toBeNull ( )
10
+ } )
11
+
12
+ it ( 'simple cycle' , ( ) => {
13
+ const head = new Node ( 1 )
14
+ head . next = new Node ( 2 )
15
+ head . next . next = new Node ( 3 )
16
+ head . next . next . next = head . next // Creates a cycle
17
+
18
+ expect ( findCycleStart ( head ) ) . toBe ( head . next )
19
+ } )
20
+
21
+ it ( 'long list with cycle' , ( ) => {
22
+ const head = new Node ( 1 )
23
+ head . next = new Node ( 2 )
24
+ head . next . next = new Node ( 3 )
25
+ head . next . next . next = new Node ( 4 )
26
+ head . next . next . next . next = new Node ( 5 )
27
+ head . next . next . next . next . next = head . next . next // Cycle
28
+
29
+ expect ( findCycleStart ( head ) ) . toBe ( head . next . next )
30
+ } )
31
+
32
+ it ( 'cycle on last node' , ( ) => {
33
+ const head = new Node ( 1 )
34
+ head . next = new Node ( 2 )
35
+ head . next . next = head
36
+
37
+ expect ( findCycleStart ( head ) ) . toBe ( head )
38
+ } )
39
+ } )
You can’t perform that action at this time.
0 commit comments