Mastering the Fast‑Slow Pointer: Detect Cycles, Palindromes, and Loops in O(1) Space
This article explains the fast‑slow (tortoise‑hare) pointer technique, lists its common applications such as cycle detection, middle‑node finding, palindrome checking, and demonstrates three LeetCode‑style solutions with step‑by‑step explanations and full Python code.
The fast‑slow pointer technique, also known as Floyd's Tortoise and Hare algorithm, uses two pointers moving at different speeds to traverse a data structure and reveal hidden patterns such as cycles or symmetry. Because it requires only constant extra space, it is widely used for linked‑list and array problems.
Practical Applications of the Fast‑Slow Pointer
Detecting cycles in linked lists or graphs.
Finding the middle node of a linked list.
Checking whether a linked list is a palindrome.
Locating the intersection node of two linked lists.
Fast‑Slow Pointer Problem Examples
Example 1: Linked List Cycle (Easy)
Goal: Given the head of a singly‑linked list, determine whether the list contains a cycle.
Initialize two pointers slow and fast at the head.
Move slow one step and fast two steps in each iteration.
If fast reaches the end, no cycle exists (return False).
If slow and fast meet, a cycle is detected (return True).
def hasCycle(head: ListNode) -> bool:
slow, fast = head, head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
return True
return FalseExample 2: Palindrome Linked List (Medium)
Goal: Determine whether a singly‑linked list reads the same forward and backward.
Use two pointers to find the list's middle.
Reverse the second half of the list in‑place.
Compare nodes from the first half with nodes from the reversed second half.
If any pair differs, the list is not a palindrome (return False); otherwise, return True.
def isPalindrome(head: ListNode) -> bool:
if not head or not head.next:
return True
slow, fast = head, head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
# Reverse second half
prev, curr = None, slow
while curr:
next_node = curr.next
curr.next = prev
prev = curr
curr = next_node
first_half, second_half = head, prev
while second_half:
if first_half.val != second_half.val:
return False
first_half = first_half.next
second_half = second_half.next
return TrueExample 3: Cycle in a Circular Array (Hard)
Goal: Given an integer array that may contain positive and negative values, decide whether a cycle exists where all moves follow the same direction.
Iterate over each index as a potential start.
Maintain slow and fast pointers that move according to the array values.
Skip already visited elements by marking them (e.g., with a sign change).
If the pointers meet and the cycle length is greater than one, a valid loop is found.
Otherwise, continue until all elements are processed.
def circularArrayLoop(nums: List[int]) -> bool:
n = len(nums)
for i in range(n):
slow, fast = i, i
direction = 1 if nums[i] > 0 else -1
while True:
slow = (slow + nums[slow]) % n
if nums[slow] * direction <= 0:
break
fast = (fast + nums[fast]) % n
if nums[fast] * direction <= 0:
break
fast = (fast + nums[fast]) % n
if slow == fast:
next_node = (slow + nums[slow]) % n
if next_node == slow:
break
return True
return FalseThese three examples illustrate how the fast‑slow pointer method can solve a variety of interview‑style problems efficiently, using only O(1) extra memory while keeping time complexity linear.
Code Mala Tang
Read source code together, write articles together, and enjoy spicy hot pot together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
