mirror of
https://github.com/TheAlgorithms/JavaScript.git
synced 2025-07-05 00:01:37 +08:00

* 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 <appgurulars@gmx.de>
58 lines
1.2 KiB
JavaScript
58 lines
1.2 KiB
JavaScript
/**
|
|
* A LinkedList based solution for finding the starting node of the cycle in a list.
|
|
* @returns the node where cycle begins in the linked list. If there is no cycle present, returns null.
|
|
* @see https://en.wikipedia.org/wiki/Cycle_detection
|
|
* @see https://leetcode.com/problems/linked-list-cycle-ii/
|
|
*/
|
|
|
|
function findCycleStart(head) {
|
|
let length = 0
|
|
let fast = head
|
|
let slow = head
|
|
|
|
while (fast !== null && fast.next !== null) {
|
|
fast = fast.next.next
|
|
slow = slow.next
|
|
if (fast === slow) {
|
|
length = cycleLength(slow)
|
|
break
|
|
}
|
|
}
|
|
|
|
if (length === 0) {
|
|
// If there is no cycle, return null.
|
|
return null
|
|
}
|
|
|
|
let ahead = head
|
|
let behind = head
|
|
// Move slow pointer ahead 'length' of cycle times
|
|
while (length > 0) {
|
|
ahead = ahead.next
|
|
length--
|
|
}
|
|
|
|
// Now move both pointers until they meet - this will be the start of cycle
|
|
while (ahead !== behind) {
|
|
ahead = ahead.next
|
|
behind = behind.next
|
|
}
|
|
|
|
// return the meeting node
|
|
return ahead
|
|
}
|
|
|
|
// head is a node on a cycle
|
|
function cycleLength(head) {
|
|
// How long until we visit head again?
|
|
let cur = head
|
|
let len = 0
|
|
do {
|
|
cur = cur.next
|
|
len++
|
|
} while (cur != head)
|
|
return len
|
|
}
|
|
|
|
export { findCycleStart }
|