Python 3.11+
The examples use the standard Python syntax and containers supported by the browser Judge; the Fast and Slow Pointers invariant is independent of a minor Python release.
Verify in Python docs(opens in a new tab)Advance pointers at different speeds to detect cycles, middles, or repeated state. Learn its decision rule, maintained state, Python cost model, and transfer from a focused drill to a full Interview Problem.
Recognize it when
Consider Fast and Slow Pointers when the prompt's constraints and required operations match this shape: Advance pointers at different speeds to detect cycles, middles, or repeated state.

Sign in to save your code and progress across devices. The lesson and problem statement remain public.
When two pointers follow the same deterministic successor at different speeds, their relative position changes without extra memory. On an acyclic chain fast reaches null; inside a cycle fast eventually laps slow.
Advance slow one edge and fast two, checking both fast and next(fast) before dereferencing. A meeting proves both pointers are inside the cycle, though it does not yet identify the entry.
def pointer_meeting_trace(next_indices, head):
slow = fast = head
trace = []
while fast != -1 and next_indices[fast] != -1:
slow = next_indices[slow]
fast = next_indices[next_indices[fast]]
trace.append([slow, fast])
if slow == fast: break
return traceImplement pointer_meeting_trace(next_indices, head). Return each [slow, fast] state through the first meeting or null termination.
Loading interactive editor.If it does not appear, the reference and starter code remain readable.Reload editor
After a meeting, place one pointer at the head and move both one step. Their equal-distance paths meet at the entry because the pre-cycle distance matches the remaining modular distance around the cycle.
def cycle_entry_index(next_indices, head):
slow = fast = head
while fast != -1 and next_indices[fast] != -1:
slow = next_indices[slow]
fast = next_indices[next_indices[fast]]
if slow == fast:
finder = head
while finder != slow:
finder = next_indices[finder]
slow = next_indices[slow]
return finder
return -1Implement cycle_entry_index(next_indices, head). Return the cycle entry using Floyd's two phases, or -1 for an acyclic chain.
Loading interactive editor.If it does not appear, the reference and starter code remain readable.Reload editor
Use fast/slow when the state transition is deterministic and O(1) auxiliary space matters. A visited set is often easier to generalize and can report the first repeated state directly, but costs O(n) space. Both approaches take O(n) time.
Say: “Fast gains one step per iteration inside the cycle, so it must meet slow. Resetting one pointer makes their remaining distances to the entry equal.” Also explain the null guards. Find the Duplicate Number(opens in a new tab) models array values as successor links.
Python 3.11+
The examples use the standard Python syntax and containers supported by the browser Judge; the Fast and Slow Pointers invariant is independent of a minor Python release.
Verify in Python docs(opens in a new tab)Interview bounds depend on the stated representation, input model, and real Python operations.
| Operation | Average | Worst | Interview note |
|---|---|---|---|
| Fast and Slow Pointers decision loop | O(n) | O(n) | A runner moving twice as fast reaches the end when a one-step runner reaches the midpoint, without counting length first. After each loop, slow has advanced one link for every two links attempted by fast. |
O(1) for the focused Trace Fast and Slow Pointers implementation.
These are the mistakes most likely to survive a happy-path example and fail a boundary case.
Applying the pattern without proving its ordering, monotonicity, or window invariant can silently miss valid candidates.
Prevent it: Write the decision rule beside the loop and verify it against Trace Fast and Slow Pointers before optimizing.
Avoid
def middle_link_index(next_indices, head):
passUse instead
def middle_link_index(next_indices, head):
slow = fast = head
while fast != -1 and next_indices[fast] != -1:
slow = next_indices[slow]
fast = next_indices[next_indices[fast]]
return slowWhere you will hit this: Trace Fast and Slow Pointers(opens in a new tab)
Stops before the final two-step advance and returns the first middle node for even-length chains.
Prevent it: Use the public tests and preserve this state: Both pointers follow the same deterministic successor relation.
Avoid
def middle_link_index(next_indices, head):
slow = fast = head
while fast != -1 and next_indices[fast] != -1 and next_indices[next_indices[fast]] != -1:
slow = next_indices[slow]
fast = next_indices[next_indices[fast]]
return slowUse instead
def middle_link_index(next_indices, head):
slow = fast = head
while fast != -1 and next_indices[fast] != -1:
slow = next_indices[slow]
fast = next_indices[next_indices[fast]]
return slowWhere you will hit this: Trace Fast and Slow Pointers(opens in a new tab)
Python slicing, copying, membership in lists, or repeated sorting inside the loop can invalidate the intended complexity.
Prevent it: Count every slice, copy, sort, membership check, and container update before claiming O(n).
Avoid
def middle_link_index(next_indices, head):
slow = fast = head
while fast != -1 and next_indices[fast] != -1 and next_indices[next_indices[fast]] != -1:
slow = next_indices[slow]
fast = next_indices[next_indices[fast]]
return slowUse instead
def middle_link_index(next_indices, head):
slow = fast = head
while fast != -1 and next_indices[fast] != -1:
slow = next_indices[slow]
fast = next_indices[next_indices[fast]]
return slowWhere you will hit this: Find the Duplicate Number(opens in a new tab)
Official Python documentation supports language behavior. Canonical problem pages provide additional practice context.
python-docs · checked 2026-07-27