Tortoise & Hare
The tortoise & hare is a technique used to detect cycles in linked lists or sequences. It’s a two-pointer approach where one pointer (the "tortoise") moves one step at a time while the other pointer (the "hare") moves two steps. If there is a cycle, the hare will eventually meet the tortoise.
It's called "tortoise & hare" because tortoises are slow and hares are fast.
When to use it
You can identify problems that can be solved using the tortoise and hare technique if they meet one or more of these conditions:
- The problem involves a linked list or a sequence.
- You're tasked with determining if a cycle exists in the structure.
- The solution needs to run in constant space ( space complexity).
Why use it
Tortoise & Hare provides an efficient way to detect cycles with minimal space usage. It operates with O(n) time complexity but only requires space, which makes it ideal for situations where memory consumption is a concern, such as working with large linked lists.
How it works
The idea is to have two pointers starting from the head of the list or sequence. The slow pointer moves one step at a time, while the fast pointer moves two steps at a time. If the fast pointer ever "catches up" to the slow pointer, it means there’s a cycle.
For example, consider a linked list where some nodes may form a cycle. If the slow and fast pointers meet, you know there’s a cycle. If the fast pointer reaches the end (null), the list has no cycle.
Pythonclass ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def has_cycle(head: ListNode) -> bool:
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
return True
return False

Not just for cycle detection: The tortoise & hare technique can also be used to solve other problems involving linked lists, such as finding the middle of a list. You can set a slow and fast pointer such that when the fast pointer reaches the end of the list, the slow pointer will be at the middle.
Pythondef find_middle(head: ListNode) -> ListNode:
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
return slow # slow will be at the middleExamples
- Finding the length of a cycle in a linked list
- Problem: After detecting a cycle in a linked list, determine its length.
- Approach: Once the slow and fast pointer meet, keep one pointer fixed and move the other around the cycle until it returns to the same point, counting the steps.