Two pointers, two speeds: slow moves 1 step, fast moves 2.
Focus on recognizing:
“Middle of list” / “cycle detection” / “no extra space allowed” → fast & slow
Pattern 1: Middle of Linked List
Two pointers, one lap speed difference — slow lands on the middle. Press ▶ to animate.
⚠️ Animation & Content Notice
The animation work is not fully finished — some animations may have slight errors.
If there is a major error in the content or if the animation or content is difficult to understand, please contact us at rayyancodingschool@gmail.com.
Middle of the Linked List
Return the middle node of a singly linked list using slow/fast pointers.
Run two pointers: slow advances one step, fast advances two. When fast reaches the end, slow is at the middle. For even length slow lands on the second middle.
1
slow = fast = head
2
while fast and fast.next:
3
slow = slow.next
4
fast = fast.next.next
5
return slow
When fast hits the end, slow is at the middle:
public ListNode middleNode(ListNode head) {
ListNode slow = head, fast = head;
while (fast != null && fast.next != null) {
slow = slow.next; // 1 step
fast = fast.next.next; // 2 steps
}
return slow;
}def middle_node(head):
slow = fast = head
while fast and fast.next:
slow = slow.next # 1 step
fast = fast.next.next # 2 steps
return slowListNode* middleNode(ListNode* head) {
ListNode *slow = head, *fast = head;
while (fast && fast->next) {
slow = slow->next; // 1 step
fast = fast->next->next; // 2 steps
}
return slow;
}function middleNode(head) {
let slow = head,
fast = head;
while (fast && fast.next) {
slow = slow.next; // 1 step
fast = fast.next.next; // 2 steps
}
return slow;
}Even length → returns the second middle. Use
fast.next.nextstart conditions to pick the first.
Pattern 2: Cycle Detection + Cycle Start
Floyd’s detectors chasing each other through a loop — the gap closes by one each round until they land on the same node. Press ▶ to animate.
⚠️ Animation & Content Notice
The animation work is not fully finished — some animations may have slight errors.
If there is a major error in the content or if the animation or content is difficult to understand, please contact us at rayyancodingschool@gmail.com.
Fast & Slow Pointers
Use two pointers moving at different speeds to locate the middle of a list and to detect cycles.
slow advances one step while fast advances two; when fast reaches the end, slow is exactly at the middle.
1
slow = fast = head
2
while fast && fast.next:
3
slow = slow.next // 1 step
4
fast = fast.next.next // 2 steps
5
return slow // middle
1
slow = fast = head
2
while fast && fast.next:
3
slow = slow.next; fast = fast.next.next
4
if slow == fast: MEET → cycle
5
# find entry:
6
p = head; q = meet
7
while p != q: p = p.next; q = q.next
8
return p // cycle start
Floyd’s algorithm — if they meet, there’s a cycle:
public boolean hasCycle(ListNode head) {
ListNode slow = head, fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) return true;
}
return false;
}def has_cycle(head):
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow is fast:
return True
return Falsebool hasCycle(ListNode* head) {
ListNode *slow = head, *fast = head;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) return true;
}
return false;
}function hasCycle(head) {
let slow = head,
fast = head;
while (fast && fast.next) {
slow = slow.next;
fast = fast.next.next;
if (slow === fast) return true;
}
return false;
}To find where the cycle starts: after they meet, reset one pointer to head and walk both 1 step — they meet again at the entry node.
Relative speed 1 guarantees a meeting inside any cycle — that’s why it terminates.
Pattern 3: Palindrome Linked List
Find mid, reverse the tail, compare halves — O(1) space. Press ▶ to animate.
⚠️ Animation & Content Notice
The animation work is not fully finished — some animations may have slight errors.
If there is a major error in the content or if the animation or content is difficult to understand, please contact us at rayyancodingschool@gmail.com.
Palindrome Linked List
Check whether a singly linked list reads the same forwards and backwards.
Use slow/fast to find the middle, reverse the second half, then compare node-by-node with the first half. This keeps O(1) extra space versus a stack or HashSet.
1
slow/fast run → slow lands at mid
2
reverse second half
3
compare head vs mid2 stepwise
4
match all → palindrome
Find middle → reverse second half → compare halves:
public boolean isPalindrome(ListNode head) {
// 1. find middle
ListNode slow = head, fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
// 2. reverse second half
ListNode prev = null;
while (slow != null) {
ListNode next = slow.next;
slow.next = prev;
prev = slow;
slow = next;
}
// 3. compare halves
while (prev != null) {
if (head.val != prev.val) return false;
head = head.next;
prev = prev.next;
}
return true;
}def is_palindrome(head):
# 1. find middle
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
# 2. reverse second half
prev = None
while slow:
slow.next, prev, slow = prev, slow, slow.next
# 3. compare halves
while prev:
if head.val != prev.val:
return False
head, prev = head.next, prev.next
return Truebool isPalindrome(ListNode* head) {
// 1. find middle
ListNode *slow = head, *fast = head;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
}
// 2. reverse second half
ListNode* prev = nullptr;
while (slow) {
ListNode* next = slow->next;
slow->next = prev;
prev = slow;
slow = next;
}
// 3. compare halves
while (prev) {
if (head->val != prev->val) return false;
head = head->next;
prev = prev->next;
}
return true;
}function isPalindrome(head) {
// 1. find middle
let slow = head,
fast = head;
while (fast && fast.next) {
slow = slow.next;
fast = fast.next.next;
}
// 2. reverse second half
let prev = null;
while (slow) {
const next = slow.next;
slow.next = prev;
prev = slow;
slow = next;
}
// 3. compare halves
while (prev) {
if (head.val !== prev.val) return false;
head = head.next;
prev = prev.next;
}
return true;
}O(1) space — the list ends up half-reversed, which most interviewers accept (restore it if asked).
Common Mistakes
while (fast.next != null) without checking fast.
On an even-length list fast becomes null first → NullPointerException.
Comparing values to detect cycles.
Nodes can repeat values — compare references (==), never .val.
Forgetting the meeting-point math for cycle start.
Reset ONE pointer to head, move both 1 step — don’t restart fast at 2× speed.
Complexity
| Operation | Time | Space |
|---|---|---|
| Middle | O(n) | O(1) |
| Cycle detect | O(n) | O(1) |
| Palindrome | O(n) | O(1) |
Premium Content
Unlock Fast & Slow Pointers and all premium lessons with a subscription.
From ₹199.99/year — See plans