File tree Expand file tree Collapse file tree 3 files changed +97
-0
lines changed
Data-Structures/Linked-List Expand file tree Collapse file tree 3 files changed +97
-0
lines changed Original file line number Diff line number Diff line change 8282 * ** Linked-List**
8383 * [ AddTwoNumbers] ( Data-Structures/Linked-List/AddTwoNumbers.js )
8484 * [ CycleDetection] ( Data-Structures/Linked-List/CycleDetection.js )
85+ * [ CycleDetectionII] ( Data-Structures/Linked-List/CycleDetectionII.js )
8586 * [ DoublyLinkedList] ( Data-Structures/Linked-List/DoublyLinkedList.js )
8687 * [ MergeTwoSortedLinkedLists] ( Data-Structures/Linked-List/MergeTwoSortedLinkedLists.js )
8788 * [ 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