Skip to content

Commit 5a7e8d1

Browse files
Akshay73cappgurueu
andauthored
implemented CycleDetectionII code in LinkedList (TheAlgorithms#1482)
* implemented CycleTectionII code * changes made per review by appgurueu * made the changes per review by appgurueu * changes made per review by appgurueu * did some changes * fixed the test file with prettier * Simplify code, renames for clarity --------- Co-authored-by: Lars Mueller <[email protected]>
1 parent 1b66d86 commit 5a7e8d1

File tree

3 files changed

+97
-0
lines changed

3 files changed

+97
-0
lines changed

DIRECTORY.md

+1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
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 numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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 numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
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+
})

0 commit comments

Comments
 (0)