Two Pointers (Opposite Ends)

Published: (January 9, 2026 at 05:24 AM EST)
3 min read
Source: Dev.to

Source: Dev.to

Overview

This pattern uses two pointers that start from opposite ends of a data structure (array or string) and move toward each other. It is mainly used when:

  • Order matters from both ends
  • The data is sorted or symmetric
  • You are checking pairs or mirrored positions
  • You want to reduce time complexity from O(N²) to O(N)

Pointer Setup

  • left → starts at index 0
  • right → starts at index n – 1

Loop Condition

Continue while left < right.

Pointer Movement Logic

  • If the current condition is satisfied: update the answer and move pointers.
  • If the value is too small: move left forward.
  • If the value is too large: move right backward.

Time & Space

  • Time Complexity: O(N)
  • Space Complexity: O(1)

Examples

Example 1: Two Sum (Sorted Array)

Problem:
Given a sorted array, determine if there exists a pair whose sum equals a target.

Logic:

  • If the sum is smaller than the target, increase left to get a bigger sum.
  • If the sum is larger than the target, decrease right to get a smaller sum.
def two_sum_sorted(nums, target):
    left = 0
    right = len(nums) - 1

    while left < right:
        current_sum = nums[left] + nums[right]

        if current_sum == target:
            return True
        elif current_sum < target:
            left += 1
        else:
            right -= 1

    return False

Example 2: Palindrome Check

Problem:
Check whether a string is a palindrome.

Logic:

  • Characters at symmetric positions must match.
  • Any mismatch immediately returns False.
def is_palindrome(s):
    left = 0
    right = len(s) - 1

    while left < right:
        if s[left] != s[right]:
            return False
        left += 1
        right -= 1

    return True

Example 3: Container With Most Water

Problem:
Find two vertical lines that, together with the x‑axis, form a container holding the maximum amount of water.

Logic:

  • Area depends on width and the smaller height.
  • Move the pointer with the smaller height to try increasing the area.
def max_area(height):
    left = 0
    right = len(height) - 1
    max_water = 0

    while left < right:
        width = right - left
        current_height = min(height[left], height[right])
        max_water = max(max_water, width * current_height)

        if height[left] < height[right]:
            left += 1
        else:
            right -= 1

    return max_water

Example 4: Reverse Array In‑Place

Problem:
Reverse an array without using extra space.

Logic:

  • Swap elements at symmetric positions.
  • Move inward until the pointers meet.
def reverse_array(arr):
    left = 0
    right = len(arr) - 1

    while left < right:
        arr[left], arr[right] = arr[right], arr[left]
        left += 1
        right -= 1

    return arr

Identification Checklist

Ask these questions:

  • Are two elements compared together?
  • Do we care about values from both ends?
  • Can one side be discarded at each step?
  • Is the data sorted or symmetric?

If the answer is yes, this pattern fits.

Summary

  • Two pointers start from opposite ends.
  • Both move inward.
  • Each iteration removes impossible cases.

The approach is clean, optimal, and easy to reason about.

Back to Blog

Related posts

Read more »