You finished Phase 1. Two pointers ran through the list at different speeds, and they collided inside the cycle. You know a cycle exists. You even know the exact node where the two pointers ended up on top of each other. So here is the question that almost everyone gets wrong the first time they encounter it:
Is the collision point the start of the cycle?
Many developers — even experienced ones — assume it is. The reasoning feels airtight on the surface: “The pointers met somewhere in the cycle. That somewhere must be the entrance.” It is a seductive idea, and it falls apart the moment you think about what actually happened during Phase 1.
Recall the mechanics. The fast pointer was advancing two nodes per step while the slow pointer advanced one. By the time the slow pointer left the tail and entered the cycle, the fast pointer had already been circling inside the loop for a while — possibly for multiple full laps. The two pointers did not enter the cycle at the same time, and they did not start from the same position within the cycle. The fast pointer was chasing the slow pointer from behind, closing the gap by one node every step, until they finally landed on the same node. That collision happened at whatever node the arithmetic lined up — not at the entrance.
Think of it like two runners on a circular track. One started jogging from the parking lot while the other was already sprinting laps. When the sprinter eventually laps the jogger, they collide at some arbitrary point on the track. There is no reason whatsoever to expect that point to be the starting line.
Here is a concrete example that makes the gap undeniable. Imagine a list with 3 tail nodes (0, 1, 2) followed by a cycle of 5 nodes (3, 4, 5, 6, 7, back to 3). The cycle entrance is node 3. Run Phase 1: slow visits 0, 1, 2, 3, 4, 5 while fast visits 0, 2, 4, 6, 3, 5. They collide at node 5 — two full nodes past the entrance. If you returned node 5 as the cycle start, you would be pointing into the middle of the loop, not at its gate.
This distinction matters enormously in practice. LeetCode 142 (“Linked List Cycle II”) does not ask whether a cycle exists — it asks where the cycle begins. The collision point from Phase 1 is inside the cycle, but it is not the entrance. If you return the collision node, you return the wrong answer. You need a second phase — and that second phase requires understanding distances. The gap between “I know a cycle exists” and “I know where it starts” is exactly the gap that the next six screens will close.
Below is the rho shape from Phase 1. The slow and fast pointers have collided at a node inside the cycle. Your job: tap the node where the cycle actually begins. Most people tap the collision node first. That is the misconception we are about to dismantle.
Now you have felt the gap firsthand: the collision point sits deep inside the cycle, not at its entrance. To bridge that gap — to get from the collision to the entry — we need to understand the distances each pointer traveled during Phase 1. This is where Floyd's algorithm becomes a proof, and the proof is surprisingly short once you name the distances.
Picture the rho shape as a road with two segments. The tail runs from the
head of the list to the first node of the cycle — call that distance a
nodes. Once the slow pointer enters the cycle, it continues walking forward
some additional distance before colliding with fast — call that distance b
nodes. The full circumference of the cycle is C nodes. These three
quantities — a, b, and C — completely describe the geometry of the
collision.
Slow's distance. The slow pointer started at the head of the list. It
walked the entire tail (a nodes) to reach the cycle entrance, then continued
b more nodes into the cycle before colliding. Slow's total distance is
a + b. There is nothing more to it — slow walked every node exactly once,
tail then partial cycle.
Fast's distance. Fast also started at the head. It also walked the tail
(a nodes) and then b more nodes into the cycle to reach the collision
point. But fast moves at 2x speed, which means it was inside the cycle for
much longer than slow. While slow was still plodding through the tail, fast
was already circling the loop. By the time they collided, fast had completed
some whole number n of extra full laps around the cycle. So fast's total
distance is a + b + nC, where n >= 1.
Why n >= 1? Because fast must have gone around the cycle at least once more
than slow to catch up from behind. If the cycle is small relative to the tail,
n might be large (fast lapped many times). If the cycle is huge, n might
be exactly 1. The exact value of n does not matter for the derivation — what
matters is that it is a positive integer.
The relationship. Here is the key constraint: fast moves exactly twice as fast as slow. They started at the same time (step 0) and collided at the same time (step T). So fast's total distance equals exactly twice slow's total distance:
2(a + b) = a + b + nC
Read that equation carefully. The left side is twice slow's distance. The right side is fast's distance. They must be equal because of the 2x speed rule.
The simplification. Distribute the left side: 2a + 2b = a + b + nC.
Now subtract a + b from both sides: a + b = nC. Rearrange one more time:
a = nC - b
That single equation is the entire engine of Phase 2. It says: the tail length
(a) equals some number of full cycle laps (nC) minus the partial-cycle
distance from the entrance to the collision (b). In other words, the
distance from the head of the list to the cycle entrance is the same as the
distance from the collision point forward around the cycle back to the
entrance.
What does nC - b mean geometrically? Stand at the collision point inside
the cycle. Walk forward C - b nodes and you will arrive at the cycle
entrance (because you have completed the remaining arc of the cycle). If
n > 1, you would continue walking full laps before arriving — but those full
laps bring you back to the same spot, so nC - b lands at the same node as
C - b. The extra laps are free.
Build it yourself below. Drag each distance term into its slot — the equation will emerge piece by piece from the geometry you already understand.
You just derived a = nC - b by cancelling matching terms from both sides of
the speed equation. Now we need to turn that algebra into an algorithm — a
concrete procedure that a computer can execute to find the cycle entrance.
The equation says: the distance from the list head to the cycle entrance (a)
is the same as the distance from the collision point forward through the cycle
back to the entrance (nC - b). Two different starting positions, two
different paths, but the same number of steps to reach the same destination.
That is the operational insight. Imagine placing one pointer at the head of the list and leaving the other pointer at the collision point. Now advance both pointers one step at a time — no more speed difference, both move at the same pace. The head pointer walks along the tail toward the cycle entrance. The collision pointer walks forward through the cycle, also toward the entrance but from the other direction.
After exactly a steps, the head pointer has traversed the entire tail and
arrives at the cycle entrance. Meanwhile, the collision pointer has walked a
steps forward through the cycle. But a = nC - b, so those a steps
correspond to walking nC - b nodes. Starting from a position b nodes past
the entrance and walking nC - b nodes forward means completing n - 1 full
laps and then walking C - b more nodes — which lands exactly at the entrance.
They meet. Not approximately, not under special conditions — the algebra guarantees convergence at the entrance for any rho shape with any tail length, any cycle length, and any number of Phase 1 laps.
Let us trace a concrete example to make this visceral. Consider the rho shape
with tail length 3 and cycle length 5. After Phase 1, the collision happens at
node 5 (which is 2 nodes past the entrance at node 3). So a = 3, b = 2,
C = 5, and nC - b = 5 - 2 = 3. Both pointers need exactly 3 steps:
Three steps each, arriving at the same node. The collision pointer wrapped around the end of the cycle (node 7 wraps back to node 3, the entrance) while the head pointer simply walked the tail. Different paths, same distance, same destination.
This is Phase 2 of Floyd's algorithm: reset one pointer to the head, keep the other at the collision, walk both at speed 1, stop when they meet. The meeting point is always the cycle entrance.
Notice how simple the procedure is. There is no computation of a, b, C,
or n at runtime. You do not need to know the tail length or the cycle length
or the number of laps. The algorithm does not measure those quantities — it
simply performs the walk and lets the geometry enforce the convergence. The
equation a = nC - b is the proof that the walk terminates at the right
place, but the walk itself is just two next pointer dereferences in a loop.
This is what makes Floyd's algorithm elegant: the math is deep, but the code is shallow. The complexity lives in the proof, not in the implementation. A developer who understands the proof can write the code from memory in four lines. A developer who memorizes the code without understanding the proof will never be confident that it works — and will never know when it is safe to adapt.
Watch it happen below. Predict each step before the pointers move — you should be able to anticipate exactly when and where they converge.
Both pointers move 1 step. Will they be closer to meeting?
That demonstration used a specific rho shape: tail length 3, cycle length 5. A healthy skepticism says, "Sure, that worked for this configuration. But what if the tail were longer? What if the cycle were tiny? What if the fast pointer went around the cycle seventeen times during Phase 1?"
This is exactly the right instinct. In mathematics, a single example proves
nothing. What you need is confidence that the equation a = nC - b holds for
any rho geometry — and that Phase 2 always terminates at the entry regardless
of the proportions.
Let us think about what changes when the geometry varies. If you stretch the
tail (increase a), the collision point shifts: slow enters the cycle later,
and fast may have completed more laps before they collide. The value of b
changes. The number of extra laps n may change. But the equation still holds
because it is derived from the fundamental relationship fast distance = 2 × slow distance, which is true regardless of shape. That 2x speed ratio is a
physical invariant of the algorithm, not a property of the specific list.
What about the Phase 2 step count? The equation a = nC - b tells us that the
head pointer walks exactly a steps. So Phase 2 always takes exactly a steps
— the tail length. The cycle length only determines where inside the cycle
the collision happened (which affects b and n), but it does not affect the
number of Phase 2 steps. A cycle of length 3 and a cycle of length 300 both
produce a Phase 2 that finishes in exactly a steps, because the collision
pointer's path through the cycle is always nC - b = a steps long.
This is a powerful invariant: Phase 2 step count = tail length, always. It means you can predict the cost of Phase 2 without knowing anything about the cycle's internal structure. All you need is the tail length, which Phase 2 itself measures implicitly by walking from head to entry.
Phase 2 steps = tail length
Consider what would happen if the equation didn't hold for some geometry. The
two pointers would walk their respective paths and miss each other — the head
pointer would arrive at the entrance while the collision pointer was somewhere
else in the cycle, or vice versa. They would keep walking forever, circling the
cycle without meeting, and the algorithm would infinite-loop. The fact that the
equation is derived purely from fast = 2 * slow (a property of the algorithm
itself, not of the list) means this cannot happen. The proof is unconditional.
There is one more subtlety worth noting. The value of n (the number of extra
laps fast completed during Phase 1) varies with the geometry. For a short cycle
and a long tail, n might be 5 or 10. For a long cycle and a short tail, n
is often 1. But n never appears in the Phase 2 procedure — it only appears in
the proof. The algorithm works because of n, but it never computes n.
This is a hallmark of mathematical elegance: the proof requires a variable that
the implementation never needs to touch.
Try it yourself. The slider below lets you adjust the tail length while keeping the cycle length fixed at 5. For each configuration, predict whether Phase 2 will take more or fewer steps — then watch the simulation confirm that the step count always equals the tail length.
You have now built every piece of Floyd's cycle-entry algorithm from first
principles. Phase 1 detects the cycle by running two pointers at different
speeds until they collide. Phase 2 finds the entrance by resetting one pointer
to the head and walking both at the same speed until they meet. Separately,
each phase makes sense. But the real test is running them back-to-back on the
same list, watching the state hand off from Phase 1 to Phase 2 seamlessly.
Notice the deep asymmetry between the two phases. Phase 1 uses speed difference to force a collision: fast moves at 2x, slow at 1x, and the gap closes by one node per step until they land on the same node. Phase 2 uses position difference with equal speed to force convergence: one pointer starts at the head, the other at the collision, and both walk at 1x until they meet. Same underlying technique (two pointers converging), completely different mechanism (speed gap vs. position gap).
Now consider the complexity. Phase 1 takes at most a + C steps. Here is why:
slow walks a steps to enter the cycle, then at most C more steps before
fast catches up (because fast closes the gap by 1 per step, and the maximum
initial gap inside the cycle is C - 1). Phase 2 takes exactly a steps, as
we proved. Total time: O(a + C) + O(a) = O(n), where n is the number of nodes
in the list. Space: O(1) — just two pointer variables.
Compare this to the hash-set approach. A hash set stores every visited node and
returns the first duplicate. That is O(n) time but O(n) space. Floyd's achieves
the same time complexity with zero extra memory. No hash set, no node
modification, no marking bits, no extra data structures. Just two pointers and
one equation.
There is a deeper lesson here about algorithm design. The hash-set approach is
obvious: store what you have seen, stop when you see it again. It is correct,
efficient in time, and easy to implement. But it uses O(n) extra memory, which
matters in constrained environments (embedded systems, interviews that require
O(1) space, or situations where the list is enormous). Floyd's algorithm trades
conceptual simplicity for spatial efficiency. The 2x-speed trick and the
reset-and-walk trick are not obvious — they require a proof to justify — but
they eliminate the space overhead entirely. This is the tradeoff you will see
again and again in algorithms: cleverness in design can replace brute force in
resources.
Also notice the handoff between phases. Phase 1 ends with both pointers at the collision node. Phase 2 begins by moving one pointer to the head and keeping the other in place. The only information that flows from Phase 1 to Phase 2 is the position of the collision pointer. Phase 2 does not need to know the cycle length, the tail length, or the number of laps. It just needs one pointer at the head and one at the collision, and the walk does the rest.
The full algorithm in pseudocode:
// Phase 1: Detect collisionlet slow = headlet fast = headwhile (fast && fast.next) { slow = slow.next fast = fast.next.next if (slow === fast) break // collision}// Phase 2: Find entryslow = headwhile (slow !== fast) { slow = slow.next fast = fast.next}return slow // cycle entryWatch the full algorithm run below on a rho shape with tail 3 and cycle 4. Predict the key transitions: when will Phase 1 collide, and where will Phase 2 converge?
Every variable in Floyd's Phase 2 implementation maps directly to a distance you measured, a segment you traced, or a node you touched in the rho shape. This is one of those rare algorithms where the code is not merely implementing the math — it is the math. Each line of code is a direct statement in the proof, and every algebraic term has a physical meaning in the linked list.
Let us walk through the Phase 2 code line by line and connect each statement
to the equation a = nC - b.
// Phase 2: Find cycle entryfunction findEntry(head: ListNode) { // Phase 1 already found collision let slow = head // reset to head let fast = collision // stays at collision while (slow !== fast) { // walk until convergence slow = slow.next // walk distance a fast = fast.next // walk distance nC - b } return slow // entry point found}slow = head — This is the reset. After Phase 1, slow was sitting at the
collision point inside the cycle. This line moves it back to the very beginning
of the list, at distance 0 from the head. In the equation, this sets up the
left-hand path: slow will walk a steps along the tail to reach the entrance.
fast = collision — Fast stays where it is. It sits at the collision
point, which is b nodes past the cycle entrance. In the equation, this sets
up the right-hand path: fast will walk nC - b steps through the cycle to
reach the entrance.
while (slow !== fast) — This is the convergence loop. The equation
a = nC - b guarantees that after exactly a iterations, both pointers will
be at the same node (the cycle entrance). The loop terminates because the
distances are provably equal. There is no infinite-loop risk: a is finite
(the tail has a finite number of nodes), and nC - b is equal to a, so both
pointers advance the same number of times before meeting.
slow = slow.next — Each iteration, slow advances one node along the
tail (and eventually into the cycle, though it arrives at the entrance before
needing to go further). After a iterations, slow has walked from node 0 to
node a — the cycle entrance.
fast = fast.next — Each iteration, fast advances one node through the
cycle. Note the critical difference from Phase 1: fast moves at speed 1 now,
not speed 2. After a iterations (which equals nC - b iterations), fast has
walked from the collision point forward through the cycle and arrived at the
entrance.
return slow — Both pointers are at the cycle entrance. Return either
one. The answer is the same.
Most algorithms have an implementation gap: the code does something, and you squint to see how it connects to the underlying idea. Floyd's Phase 2 has no gap. The equation is the loop. The geometry is the control flow. Every variable name could be replaced by its algebraic meaning and the code would still read as a valid proof.
Below, you can tap any element — an equation term, a code line, or a concept label — and see the corresponding elements light up across all three panels. Explore every connection, then prove you can wire them from memory.
0/5 connections explored
Three rho shapes. Each one tests a different aspect of your understanding of
a = nC - b and Phase 2 convergence. By now you have the equation, the
geometric intuition, and the code. These final challenges check whether you can
transfer that knowledge to unfamiliar configurations without falling back on
memorization.
Shape 1: The balanced case. Tail length 4, cycle length 4. This is a symmetric rho where the tail and cycle are the same size. If slow and fast collide at node 6 (two nodes past the entrance at node 4), how many Phase 2 steps are needed? You already know the answer pattern — the step count equals the tail length — but can you predict it instantly without working through the arithmetic? This shape tests your fluency: the equation should feel automatic, not effortful.
Shape 2: The zero-tail edge case. Tail length 0, cycle length 6. The
entire list is one big cycle with no tail at all. The head of the list is
already inside the cycle — in fact, the head is the cycle entrance. Think
carefully about what a = 0 means for Phase 2. The head pointer starts at the
entrance. The collision pointer... also starts at the entrance (because with
a = 0 and nC - b = 0, the collision point is the entrance). The loop
while (slow !== fast) checks the condition, finds them already equal, and
exits immediately. Phase 2 takes zero steps. The algorithm handles this edge
case for free — no special-case code required. This is the mark of a correct
derivation: edge cases fall out of the math naturally rather than requiring
defensive if checks.
Shape 3: The long-tail stress test. Tail length 6, cycle length 3. The
tail is twice as long as the cycle. During Phase 1, fast entered the cycle
early and lapped it many times while slow was still trudging through the tail.
The value of n (extra laps) is high. But Phase 2 does not care about n at
all — it cares about a, the tail length. Phase 2 will take exactly 6 steps,
regardless of how many laps fast completed during Phase 1. This shape tests
whether you have truly internalized that Phase 2's cost is governed by the tail
alone. The cycle length affects where the collision happens (it determines b
and n), but it does not affect how many steps Phase 2 needs.
Together, these three shapes span the space of rho geometries you will
encounter in practice: balanced proportions, degenerate no-tail, and
tail-dominated. If you can predict the behavior of Phase 2 across all three
without hesitation, you own Floyd's algorithm at a level that goes beyond
memorization. You understand why it works, which means you can adapt it,
debug it, and explain it to others with confidence.
The equation a = nC - b is your anchor. When in doubt, return to it. The
tail length determines Phase 2's cost. The cycle length determines Phase 1's
collision point. The speed ratio (2x) guarantees the equation holds. Everything
else follows.
Each shape reveals its simulation after your prediction. Watch whether the equation holds — it always does.
If slow and fast collide at node 6, how many Phase 2 steps to find the entry?