Skip to main content

Two Pointers: Cycle Finding

Linked List Cycle II

This question is the same as Linked List Cycle,
except in addition to checking whether a linked list has a loop,
we also find the size of the loop, if applicable.

Parameters
nodes: The first node of a linked list with potentially a loop.

Result
An integer representing the size of the loop, if there is one. If there is no loop, output -1.

Example 1
Input: 0 -> 1 -> 2 -> 3 -> 4
^ |
|_ _ _ _ _ _ _

Output: 4 (there is a loop of size 4, starting from node 1)

Example 2
Input: 0 -> 1 -> 2 -> 3 -> 4

Output: -1 (there is no loop)

Constraints
1 <= len(nodes) <= 10^5
class Node {
constructor(val, next=Null) {
this.val = val;
this.next = next;
}
}

function nodeNext(node) {
return node.next || node;
}

function cycleSize(nodes) {
let tortoise = nodeNext(nodes);
let hare = nodeNext(nodeNext(nodes));
while (tortoise !== hare && hare.next) {
tortoise = nodeNext(tortoise);
hare = nodeNext(nodeNext(hare));
}
if (!hare.next) return -1;
let count = 1;
tortoise = nodeNext(tortoise);
hare = nodeNext(nodeNext(hare));
while (tortoise !== hare) {
count++;
tortoise = nodeNext(tortoise);
hare = nodeNext(nodeNext(hare));
}
return count;
}

linkedListCycleII

Explanation

  • The basic idea is the same as in Linked List Cycle, except how do we determine the size of the loop?
    • Let's say that the loop size is r and the tortoise and the hare already met up
    • They must both be inside the loop, otherwise they cannot be at the same location
    • Let's say that after k cycle, they meet up again
      • In that case, k % r == 2k % r, which means that k % r == 0
      • The smallest k where this is possible is when k == r
    • This means that after they meet, we start counting the number of cycles that passed until they meet again
      • Then, that must be the size of the cycle
  • Time Complexity: O(n)