Introduction
In our last lesson, you saw how the fast and slow pointer technique could brilliantly solve the "Linked List Cycle" problem by detecting if a cycle exists with space. We ended with a classic interview follow-up: "Great, but can you find the exact node where the cycle begins?"
Today, we will answer that question and complete your mastery of Floyd's Tortoise and Hare algorithm. Your learning outcome is to detect a cycle in a linked list and identify its starting point. We'll break down the elegant two-phase approach, dive into the mathematical proof that makes it work, and analyze its trade-offs—a perfect deep-dive for an elite interview preparation.
Concept 1: Problem Definition and The Naive Approach
First, let's precisely define the problem. Given the head of a linked list, which may or may not contain a cycle, our task is to return the node where the cycle begins. If there is no cycle, we should return null.

Technical Explanation: The Hash Set Method
Before jumping to the optimal solution, let's consider a more straightforward approach. We can traverse the list one node at a time and store each node we visit in a hash set (or hash map). Before visiting a new node, we check if it's already in our set. The first time we encounter a node that's already in the set, we've found the starting point of the cycle.
This works correctly, but it comes at a cost. Storing every node requires extra memory. In the worst case, for a list of size , the space complexity is . In an interview, you'd be immediately asked to optimize this.
Metaphor: Dropping Breadcrumbs
Imagine walking through a maze. The hash set method is like dropping a breadcrumb at every intersection you pass. If you arrive at an intersection and see a breadcrumb already on the ground, you know you've been there before and have just found a loop. It's effective but requires you to carry a large bag of breadcrumbs.
Python Code Snippet: Hash Set Approach
# Definition for singly-linked list node.
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def findCycleStart_hashset(head: ListNode) -> ListNode:
"""
Finds the start of a cycle using a hash set.
Time Complexity: O(N)
Space Complexity: O(N)
"""
visited_nodes = set()
current = head
while current:
if current in visited_nodes:
# We've seen this node before, it's the start of the cycle.
return current
visited_nodes.add(current)
current = current.next
# If the loop finishes, there is no cycle.
return None
This sets our baseline. Now, let's see how Floyd's algorithm achieves the same result with constant space.
Concept 2: Floyd's Algorithm - Phase 1: Collision
This first phase is exactly what we covered in the last lesson: detecting the cycle's existence. It's the "Tortoise and Hare" race.
Technical Explanation
We initialize two pointers, slow and fast, at the head of the list.
slowmoves one step at a time:slow = slow.next.fastmoves two steps at a time:fast = fast.next.next.
If the list has no cycle, the fast pointer will eventually reach the end (None), and we're done. However, if a cycle exists, the fast pointer will enter it first and start "lapping" the slow pointer. Since the fast pointer gains one position on the slow pointer at every step within the cycle, they are guaranteed to meet. This meeting point is often called the "collision point".
Metaphor: Runners on a Track
Imagine two runners starting at the same time on a track that has a straight section leading into a circular loop. One runner is twice as fast as the other. They will both run the straight section, and then enter the loop. Once in the loop, the faster runner will inevitably lap the slower runner. The spot where they meet is the collision point.
To see this phase in action, let's watch a short video segment.
Floyd's cycle detection algorithm (Tortoise and hare) - Inside code
The video 'Floyd's cycle detection algorithm' by Inside code provides a clear visual explanation of how the two pointers move and eventually meet.
Watch from 01:25 to 02:35. Focus on the animation showing the tortoise (slow) and hare (fast) pointers. Observe that if a cycle exists, they must collide somewhere inside it.
This collision proves a cycle exists, but the collision point is not necessarily the start of the cycle. That's what Phase 2 is for.
Concept 3: Floyd's Algorithm - Phase 2: Finding the Start Node
This is the clever part that builds on the collision from Phase 1.
Technical Explanation
Once slow and fast have collided, we do the following:
- Leave the
fastpointer at the collision point. - Reset the
slowpointer back to theheadof the linked list. - Now, move both pointers one step at a time (
slow = slow.next,fast = fast.next).
The node where they meet again is guaranteed to be the starting node of the cycle.
Metaphor: The "Magic" Reset
Think back to our runners. After the fast runner laps the slow one, they stop at the collision point. Now, we ask the slow runner to teleport back to the very beginning of the entire track (the head). We keep the fast runner at the collision spot. Then, we tell both runners to start jogging at the same, slow pace. The exact spot where they meet for the second time will be the entrance to the circular loop.
The video we just watched also covers this second phase beautifully.
Floyd's cycle detection algorithm (Tortoise and hare) - Inside code
Let's continue with the 'Inside code' video to see the explanation for Phase 2.
Now watch from 02:35 to 03:05. This short clip explains the procedure for Phase 2: resetting one pointer and moving both at the same speed until they meet at the cycle's entry point.
Python Code Snippet: Full Floyd's Algorithm
def findCycleStart_floyd(head: ListNode) -> ListNode:
"""
Finds the start of a cycle using Floyd's Tortoise and Hare algorithm.
Time Complexity: O(N)
Space Complexity: O(1)
"""
if not head or not head.next:
return None
# Phase 1: Find the collision point.
slow, fast = head, head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
# Collision detected. Break to start Phase 2.
break
else:
# Loop finished without collision, no cycle.
return None
# Phase 2: Find the cycle start.
# Reset one pointer to the head.
slow = head
while slow != fast:
slow = slow.next
fast = fast.next
# Both pointers now meet at the cycle's start.
return slow
Test your understanding!
In Phase 2, we reset slow to head and keep fast at the collision point. Would the algorithm still work if we reset fast to head and kept slow at the collision point?
Show answer
Yes, absolutely. The choice is arbitrary. The mathematical property we are about to explore holds true regardless of which pointer is reset. As long as one pointer starts from the head and the other from the collision point, and both move at the same speed, they will meet at the cycle's entrance.
Concept 4: The "Under the Hood" Mathematical Proof
Why does this "magic reset" work? It's not magic; it's math. This is the deep understanding that will impress an interviewer.
Technical Explanation
Let's use the variables from the diagram shown earlier:
- : The distance from the
headto the cycle's start node (length of the non-cyclic part). - : The distance from the cycle's start node to the collision point.
- : The distance from the collision point back to the cycle's start node.
- : The total length of the cycle, so .
When slow and fast collide:
- Distance traveled by
slow: - Distance traveled by
fast:- The
fastpointer has traveled the same path asslow, plus it has completed some number of full laps () within the cycle.
- The
We also know the fast pointer moves twice as fast as the slow pointer, so it has traveled twice the distance:
Now, let's substitute the distance expressions:
Rearranging the terms to solve for :
This equation is the key. Let's make it more intuitive. We know , so we can write as :
This equation tells us that the distance from the head to the cycle start () is equal to some number of full laps plus the distance from the collision point to the cycle start ().
This is precisely why Phase 2 works! When we put one pointer at the head (which will travel a distance of ) and another at the collision point (which will travel a distance of to get to the start), they are guaranteed to meet at the cycle's start node.
For a rigorous walkthrough of this derivation, the following video is one of the best available.
L17. Find the starting point of the Loop/Cycle in LinkedList | Multiple Approaches
The 'take U forward' channel provides an exceptionally clear mathematical proof. It answers the two key questions: why do the pointers collide, and why is the collision point the starting point in Phase 2?
Watch the detailed intuition from 14:22 to 21:55. The presenter uses different variable names (L1, D) but the logic is identical to our L, a, b. Pay close attention to how he relates the distances traveled by the slow and fast pointers to derive the crucial final relationship.
Concept 5: Complexity, Trade-offs, and Real-World Relevance
Understanding the algorithm is one thing; articulating its performance and place in the world is another.
Technical Explanation: Performance Analysis
| Algorithm | Time Complexity | Space Complexity | Notes |
|---|---|---|---|
| Hash Set | Simpler to reason about and implement, but consumes memory proportional to the list size. | ||
| Floyd's | Optimal space. Time is linear because pointers traverse the list a small, constant number of times. Slightly more complex logic. |
- Time Complexity of Floyd's: The slow pointer travels at most nodes before a collision. Phase 2 also takes a linear number of steps. The total time is therefore proportional to .
- Space Complexity of Floyd's: The algorithm only requires two pointers, regardless of the list size. This is a constant amount of memory, making it .
Design Decisions & Interview Context
In an interview, you should first mention the hash set approach to show you can find a working solution. Then, immediately identify its space complexity as a drawback and introduce Floyd's algorithm as the optimized, space solution. Being able to code it and then explain the mathematical proof for Phase 2 demonstrates a deep level of understanding that separates top candidates.
Real-World Applications
This isn't just an interview puzzle. The core idea of cycle detection appears in:
- Garbage Collection: Detecting circular references in memory to prevent memory leaks. If object A points to B, and B points back to A, neither can be automatically deallocated unless the cycle is detected.
- Finite State Machines: Determining if a state machine can get stuck in a loop.
- Cryptography: Pollard's rho algorithm for integer factorization uses a similar cycle-finding technique.
Conclusion
Today, you've fully dissected one of the most elegant algorithms in computer science. You not only learned the two-phase procedure of Floyd's Tortoise and Hare algorithm but also delved into the mathematical proof that underpins its correctness.
Key Takeaways:
- Two-Phase Approach: Floyd's algorithm solves this problem in two steps: 1) Detect a collision using fast and slow pointers. 2) Reset one pointer to the head, move both at the same speed, and their next meeting point is the cycle's start.
- Mathematical Foundation: The algorithm works because of a precise mathematical relationship: the distance from the head to the cycle start is equal to the distance from the collision point to the cycle start (plus some number of full cycle laps).
- Optimal Performance: The key advantage is its space complexity, making it vastly superior to the space hash set method. The time complexity remains linear, at .
- Interview Gold: This is a multi-layered problem perfect for interviews. Being able to explain the naive solution, the optimal algorithm, and the proof behind it showcases a robust problem-solving ability.
Preview of the Next Lesson
We have now concluded our deep dive into linear data structures and the clever pointer-based patterns used to manipulate them. We are moving into a new dimension of data organization: hierarchical structures. In the next lesson, you will learn to implement binary trees and perform the fundamental traversal algorithms (in-order, pre-order, post-order, and level-order). This will be our first step into the world of non-linear data structures, which are the foundation for search, indexing, and much more.