Phantom CodePhantom Code
Earn with UsBlogsHelp Center
Earn with UsBlogsMy WorkspaceFeedbackPricingHelp Center
Home/Blog/Two Pointers, Sliding Window, and Fast/Slow Pointers: Pattern Guide
By PhantomCode Team·Published April 30, 2026·5 min read
TL;DR

The two-pointers family solves a huge swath of array and linked-list interview problems in O(n) time and O(1) space. Three core variants: converging pointers on a sorted array (Two Sum II, 3Sum), sliding window with expand/contract logic (longest substring without repeats, minimum window substring), and fast/slow pointers for cycle and middle-of-list problems. Recognize the input shape — sorted, subarray, linked list — pick the variant, and you'll outperform candidates relying on hash maps.

Two pointers is a fundamental technique that solves a surprising range of interview problems efficiently. When done right, it transforms O(n²) brute-force solutions into elegant O(n) or O(n log n) solutions. The challenge: recognizing when to use two pointers and which variant applies. This guide covers the pattern, variations, and problems where two pointers shines.

The Two Pointers Mindset

Two pointers works when:

  1. You have a sequence (array or linked list)
  2. You need to find a pair or remove elements or partition data
  3. The sequence has some ordering or structure you can exploit

The core idea: Use two pointers moving in coordinated ways to explore the space efficiently.

Pattern 1: Two Pointers on Sorted Array (Converging)

Start with one pointer at the beginning, one at the end. Move them toward each other.

When to use: Find a pair with a specific sum, remove duplicates, partition into sections.

Classic Problem: Two Sum II (Sorted Array) Find two numbers that sum to a target.

def two_sum(numbers, target):
    left, right = 0, len(numbers) - 1
 
    while left < right:
        current_sum = numbers[left] + numbers[right]
        if current_sum == target:
            return [left + 1, right + 1]  # 1-indexed
        elif current_sum < target:
            left += 1  # Need larger sum
        else:
            right -= 1  # Need smaller sum
 
    return []

Time: O(n), Space: O(1)

Why it works: Array is sorted. If sum is too small, left element is too small; move left forward. If sum is too large, right element is too large; move right backward.

Variation: 3Sum Find three numbers that sum to target.

def three_sum(nums, target):
    nums.sort()
    result = []
 
    for i in range(len(nums) - 2):
        # Two sum on the rest
        left, right = i + 1, len(nums) - 1
        while left < right:
            current_sum = nums[i] + nums[left] + nums[right]
            if current_sum == target:
                result.append([nums[i], nums[left], nums[right]])
                left += 1
                right -= 1
            elif current_sum < target:
                left += 1
            else:
                right -= 1
 
    return result

Pattern 2: Sliding Window

Use two pointers to maintain a window that expands and contracts based on a condition.

When to use: Longest/shortest substring with property, character frequency problems, subarray sums.

Classic Problem: Longest Substring Without Repeating Characters

def length_of_longest_substring(s):
    char_index = {}
    max_length = 0
    left = 0
 
    for right in range(len(s)):
        if s[right] in char_index and char_index[s[right]] >= left:
            # Character already in window, move left
            left = char_index[s[right]] + 1
 
        char_index[s[right]] = right
        max_length = max(max_length, right - left + 1)
 
    return max_length

Time: O(n), Space: O(min(n, alphabet_size))

Why it works: Right pointer expands the window. When a duplicate is found, left pointer contracts until the duplicate is out. The window always contains unique characters.

Variation: Maximum Window Sum Find a subarray of size k with maximum sum.

def max_sum_subarray(nums, k):
    if k > len(nums):
        return None
 
    window_sum = sum(nums[:k])
    max_sum = window_sum
 
    for i in range(k, len(nums)):
        window_sum = window_sum - nums[i - k] + nums[i]
        max_sum = max(max_sum, window_sum)
 
    return max_sum

Variation: Minimum Window Substring Given s and t, find the minimum substring of s that contains all characters of t.

def min_window(s, t):
    if len(t) > len(s):
        return ""
 
    t_count = {}
    for char in t:
        t_count[char] = t_count.get(char, 0) + 1
 
    required = len(t_count)
    left, right = 0, 0
    formed = 0
    window_counts = {}
    ans = float('inf'), None, None
 
    while right < len(s):
        char = s[right]
        window_counts[char] = window_counts.get(char, 0) + 1
 
        if char in t_count and window_counts[char] == t_count[char]:
            formed += 1
 
        while left <= right and formed == required:
            char = s[left]
 
            if right - left + 1 < ans[0]:
                ans = (right - left + 1, left, right)
 
            window_counts[char] -= 1
            if char in t_count and window_counts[char] < t_count[char]:
                formed -= 1
 
            left += 1
 
        right += 1
 
    return "" if ans[0] == float('inf') else s[ans[1]:ans[2] + 1]

Pattern 3: Fast and Slow Pointers

Move one pointer faster than the other. Useful for linked list problems.

When to use: Detect cycles, find middle, find k-th element from end.

Classic Problem: Detect Cycle in Linked List

def has_cycle(head):
    slow = fast = head
 
    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next
 
        if slow == fast:
            return True
 
    return False

Why it works: If there's a cycle, fast pointer eventually catches slow pointer.

Variation: Find Cycle Start

def detect_cycle(head):
    slow = fast = head
 
    # Find cycle
    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next
        if slow == fast:
            break
    else:
        return None  # No cycle
 
    # Find cycle start
    slow = head
    while slow != fast:
        slow = slow.next
        fast = fast.next
 
    return slow

Why it works: When they meet, if you reset one pointer to head and move both one step at a time, they meet at cycle start.

Variation: Middle of Linked List

def find_middle(head):
    slow = fast = head
 
    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next
 
    return slow

Pattern 4: Two Pointers Moving in Same Direction

Both pointers move forward, but at different rates or conditions.

Classic Problem: Container with Most Water Given array of heights, find two lines that form a container with max area.

def max_area(height):
    left, right = 0, len(height) - 1
    max_area_val = 0
 
    while left < right:
        # Width and height of current container
        width = right - left
        h = min(height[left], height[right])
        area = width * h
        max_area_val = max(max_area_val, area)
 
        # Move the pointer pointing to smaller height
        if height[left] < height[right]:
            left += 1
        else:
            right -= 1
 
    return max_area_val

Why it works: Moving the taller line won't improve area (limited by shorter line). Only moving the shorter line can improve area.

Pattern 5: Remove Duplicates/Unwanted Elements

Use two pointers to partition array in-place.

Classic Problem: Remove Duplicates from Sorted Array

def remove_duplicates(nums):
    if not nums:
        return 0
 
    write = 0
    for read in range(1, len(nums)):
        if nums[read] != nums[write]:
            write += 1
            nums[write] = nums[read]
 
    return write + 1

Why it works: Read pointer scans all elements. Write pointer marks where unique elements go. Overwrite duplicates.

Variation: Remove Element Remove all instances of a value in-place.

def remove_element(nums, val):
    left = 0
    for right in range(len(nums)):
        if nums[right] != val:
            nums[left] = nums[right]
            left += 1
    return left

Pattern 6: Partition into Two Parts

Rearrange array so elements meeting a condition are on one side.

Classic Problem: Move Zeros to End

def move_zeros(nums):
    left = 0
    for right in range(len(nums)):
        if nums[right] != 0:
            nums[left], nums[right] = nums[right], nums[left]
            left += 1

Common Two Pointers Problems

  1. Palindrome check: Two pointers from ends.
  2. Trapping rain water: Two pointers, track max heights.
  3. Squares of sorted array: Two pointers (largest squares are at ends).
  4. Merge sorted arrays: Two pointers, merge from both arrays.
  5. Reverse array: Two pointers, swap from ends.

Time and Space Complexity

  • Two pointers on sorted array: O(n) time, O(1) space
  • Sliding window: O(n) time (each element visited twice at most), O(k) space (window size)
  • Fast/slow pointers: O(n) time, O(1) space

This is why two pointers is powerful: near-linear time with minimal extra space.

Interview Tips

  1. Identify the structure. Is it a sorted array? Linked list? Subarray problem?
  2. Choose the pattern. Converging, diverging, or same-direction movement?
  3. Clearly state your approach. "I'll use two pointers, one from each end, moving toward center..."
  4. Handle edge cases. Empty arrays, single elements, all duplicates.
  5. Test on small examples. Trace through your algorithm step-by-step.

Practicing Two Pointers

  1. Do 15-20 two pointer problems on LeetCode.
  2. For each, identify which pattern it uses.
  3. Code without looking at solutions.
  4. Optimize to O(n) time and O(1) space.
  5. Solve it multiple ways if possible.

Real Interview Scenario

Interviewer: "Given a sorted array, find two numbers that sum to a target."

Your approach:

  • "This is a two pointers problem. I'll start with one pointer at the beginning and one at the end."
  • "If the sum is too small, I move the left pointer right (to increase sum)."
  • "If the sum is too large, I move the right pointer left (to decrease sum)."
  • "When they meet or I find the target, I'm done."
  • Code it up, test on examples, analyze complexity.

Interviewer: "What if the array isn't sorted?"

Your response: "I could sort it first (O(n log n)), or use a hash map for O(n) time and O(n) space. Two pointers wouldn't work there."

Mastering Two Pointers

Two pointers is elegant and powerful. It's also one of the first techniques that separates mediocre engineers from good ones. Most candidates don't recognize two pointer problems quickly. If you master this technique, you'll solve problems in seconds that others struggle with for minutes.

Start with simple converging pointers, then move to sliding windows, then fast/slow pointers. Within a week of practice, you'll have this down.

When you're practicing and want real-time feedback on whether your two pointer approach is optimal, Phantom Code provides instant guidance. It listens to your explanation and provides suggestions on whether you're using the right pattern for the problem. All supported through a chat interface, completely invisible to your interviewer. Plans start at ₹499/month at phantomcode.co.

Final Thoughts

Two pointers is a cornerstone technique. Master it and you'll solve problems faster, with better code, and more confidently. It's the kind of technique that once you see it, it becomes obvious—but only after practice.

Frequently Asked Questions

When should you use two pointers instead of a hash map?
Use two pointers when the input is sorted or when you can sort it cheaply, and when you need O(1) extra space. Use a hash map for unsorted inputs where the O(n) extra space is acceptable.
How is sliding window different from two pointers?
Sliding window is a specialized form of two pointers where both pointers move in the same direction and you maintain state about the window between them. Generic two pointers can converge from opposite ends or move at different speeds.
Why does Floyd's cycle detection (fast/slow) actually work?
If there's a cycle, the fast pointer gains one step per iteration on the slow pointer inside the cycle, so they're guaranteed to meet within one cycle length. If there's no cycle, fast reaches null first.
How do you find the start of a cycle, not just detect one?
After fast and slow meet inside the cycle, reset slow to the head and advance both one step at a time. The point where they meet again is mathematically guaranteed to be the cycle's start.
What's the typical time and space complexity for sliding window?
O(n) time because each element is visited at most twice (once by right, once by left), and O(k) space where k is the window size or the size of the auxiliary frequency map.

Ready to Ace Your Next Interview?

Phantom Code provides real-time AI assistance during technical interviews. Solve DSA problems, system design questions, and more with instant AI-generated solutions.

Get Started

Related Articles

10 Things Great Candidates Do Differently in Technical Interviews

Ten behaviors that separate offer-winning candidates from average ones, from clarifying questions to optimizing without being asked.

From 5 Rejections to a Google Offer: One Engineer's Story

How a mid-level engineer turned five Google rejections into an L5 offer by fixing communication, system design depth, and exceptional reasoning.

Advanced SQL Interview Questions for Senior Engineers (2026)

Basic SQL gets you through L3. Senior roles require window functions, CTEs, execution plans, and real optimization know-how. Here is the complete advanced playbook.

Salary Guide|Resume Templates|LeetCode Solutions|FAQ|All Blog Posts
Phantom CodePhantom Code
Phantom Code is an undetectable desktop application to help you pass your Leetcode interviews.
All systems online

Legal

Refund PolicyTerms of ServiceCancellation PolicyPrivacy Policy

Pages

Contact SupportHelp CenterFAQBlogPricingBest AI Interview Assistants 2026FeedbackLeetcode ProblemsLoginCreate Account

Compare

Interview Coder AlternativeFinal Round AI AlternativeUltraCode AI AlternativeParakeet AI AlternativeAI Apply AlternativeCoderRank AlternativeInterviewing.io AlternativeShadeCoder Alternative

Resources

Salary GuideResume TemplatesWhat Is PhantomCodeIs PhantomCode Detectable?Use PhantomCode in HackerRankvs LeetCode PremiumIndia Pricing (INR)

Interview Types

Coding InterviewSystem Design InterviewDSA InterviewLeetCode InterviewAlgorithms InterviewData Structure InterviewSQL InterviewOnline Assessment

© 2026 Phantom Code. All rights reserved.