Floyd's Cycle Detection
' width='1512' height='2016' xlink:href='data:image/jpeg%3bbase64%2c/9j/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCABVAEADASIAAhEBAxEB/8QAGgAAAgMBAQAAAAAAAAAAAAAABQYAAwQCB//EADQQAAIBAwMDAwEHAQkAAAAAAAECAwAEEQUSIRMxQQZRYZEVIjJxgaGxFCQzVIKSwdHh8P/EABcBAQEBAQAAAAAAAAAAAAAAAAEAAgT/xAAaEQEBAQADAQAAAAAAAAAAAAAAARECEkEx/9oADAMBAAIRAxEAPwAP6YsxLZSkqMid%2bcCmKDTFJGVU/wCUVx6Ptf7NdrjtcuKbbWyzjIrjrq3AKLS4mZT0UAJxyqj9qu%2bx7YRhmgQIBy21e1Nltp68Hpjvnkeauk0qPoNhcFQSrHkg9/NTPakltFs2QFbeNl9ygH81km0GzGQ9pFnwSg5%2blegfZMbRMGAORtJGORwaH6hp4CkrtDAgZI7%2b4%2bTSryrz240Cy/wkX0oZc6FZLnbbqPyJr0S7ssA8UCvbbbnjira1Bf0lZ7ftBSO129ONpaduKF6DakHVVUNuNy%2bNpwf0NMMFrKbTHRuMlACqzjd%2bLnntn59uKPWF8VuI4yxBIHJwM10VEiAG1ndHXkGPjBHY5Nao7U9NB0iSjcF5CTjyciu7ay6ciMI4kC5wBuY9sdya1g0NSElGTpSIY14LrtB4OOBx9KwtB14opXjKsBwrLgg9jmmWYY9qwzrwakV7uABcAcClzUYVWNmfAUDJJpyvEHOKXtRQAEDIo%2btS4PaEoN5qqe1yw%2btGTFChgjV42lX7q9WZg2e/jv380B9Pyj7b1xM/huQfqtMzTdLDdeGIbTkume3nuKPWaujuTvR2lVo3UlVSJjnA55ovp7REt1ABkZ5oTFckxbmu4Dkqv3UONx8d/NWqsikF5dxGcgKAD/7/AHrUuMV3qJRJnVFIAPGKFTtwa2ztk881huGGDRWoFXZ4ODS7qZwPej10w5yaA6i4581Rp3oNzj1X6iTPaSJvqtOkMhfZtlZMHJC45%2bDmvMNIu9vrX1CM/iWEj/TTjaXrptDTwhvlccflms0bhkna42kRzSYbhSqKdh/4rV1txKmNxgZ3EDBoNHdStEenOgbPB2ZAHt3/AHq9riQj%2b%2bA%2bAoqZaJpBmh1zNwRXU9yOaGXU/BNTSi7kBzzS9qUmAa33c4weaAahcDB5phA7O72%2bs9aO/bugiOfbjvTBa6kXkiZdRTpkbeI1O5sY/nmkGC5x6v1Bs/it4zRqKd2ZskbSAoPUbJGcntjH6VVHiHU3yNl%2bzONrMiw7hgfdOOMjJBPxV91qczMDbtdAFM4KEDO7z932zxkdh70lJNOhRo5ELAHuXx5K8bq1/wBQzbC7ICoYDAbIzj5/P/qg4ZmvFwGQ3rl0HJY8Aj2J4P75oPcM0sbQlLjGAd7FecgZXnPjj9awieIIu9Iy4DAkDA57/Wsss0IUqsUaqfAHxj%2bOKlgk8wiQjqSNwBhjwPgDxQi8uc5yayzXQVQq4CgYAHih1xc9%2baYZATqFfVNwR5tl/mjUUzVKlVTStw4FWC5fFSpQ05e4es8k7kVKlIYppmrJLK1SpSX/2Q==' /%3e%3c/svg%3e)
// linked-list, two-pointer
const { LinkedList } = require('../../utils')
/*
Floyd's Cycle Detection
https://www.youtube.com/watch?v=zbozWoMgKW0
https://www.youtube.com/watch?v=LUm2ABqAs1w&feature=emb_logo
*/
function loopDetection(head) {
let slow = head,
fast = head
while (fast && fast.next) {
slow = slow.next
fast = fast.next.next
if (slow === fast) {
break
}
}
if (!fast || !fast.next) return null
slow = head
while (slow !== fast) {
slow = slow.next
fast = fast.next
}
return fast
}
// Tests
const ll1 = new LinkedList()
ll1.fromArray([1, 2, 3, 1, 2, 5])
const loopStart = ll1.head.next.next
const tail = ll1.getTail()
tail.next = loopStart
const testCases = [[ll1, loopStart]]
for (const test of testCases) {
console.log(loopDetection(test[0].head) === test[1])
}