AlgoMaster Logo

Introduction to Two Pointers

High Priority8 min readUpdated May 30, 2026
Listen to this chapter
Unlock Audio

Two pointers uses two index variables to traverse a data structure, typically an array or string. The pointers move towards each other, away from each other, or in the same direction based on the problem's requirements.

Using this approach, you can reduce the time complexity of many array and string problems from O(n²) to O(n), or to O(n log n) when sorting is required first.

This chapter covers what the Two Pointers pattern is, the common variants, and when to use it.

What is a Pointer?

A pointer is a variable that represents an index or position within a data structure, such as an array or linked list.

0
1
1
2
pointer
2
3
3
4
4
5

The pointers can represent:

  • Boundaries of a range (left and right ends)
  • Current position and a comparison position (for removing duplicates)
  • Two separate arrays (for merging or comparing)
  • Fast and slow traversal speeds (for cycle detection, covered below under same-direction pointers)

Using pointers at different positions, we can compare elements and make decisions without relying on nested loops, which would otherwise lead to O(n²) time complexity.

Variants of Two Pointers

The Two Pointers technique can be applied in different ways depending on the problem. Here are the three most common strategies.

1. Opposite Direction (Converging Pointers)

In the most common variant, one pointer starts at the beginning, the other at the end, and they move towards each other.

0
1
start
1
2
2
3
3
4
4
5
end

The pointers adjust their positions based on comparisons, until a certain condition is met, or they cross each other.

This strategy is ideal for problems where we need to compare elements from opposite ends of an array or string.

Template

Which pointer to move depends on the comparison. In sorted arrays:

  • Moving left right increases values (if sorted ascending)
  • Moving right left decreases values (if sorted ascending)

When sorting is required

Opposite-direction two pointers for pair-sum problems such as Two Sum II and 3Sum requires the array to be sorted. The technique relies on monotonicity: increasing left only increases the sum, and decreasing right only decreases it. Without that property, you cannot decide which pointer to move after a comparison.

Opposite-direction two pointers for palindrome or mirror checks does not require sorting. It relies on position symmetry, not value order, so the comparison is between characters at mirrored indices.

Same-direction variants such as read/write partition, sliding window, and fast/slow pointers generally do not require sorting either.

When sorting is required and the input is unsorted, the overall complexity becomes O(n log n) for the sort plus O(n) for the two-pointer scan, dominated by the sort.

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

Example

Checking if a string is a palindrome

A palindrome is a sequence that reads the same forward and backward (e.g., "racecar", "madam").

To check if a string is a palindrome, we:

  • Initialize two pointers: one at the beginning and one at the end.
  • Compare characters at both pointers:
    • If they match, move both pointers inward.
    • If they do not match, return false.
  • Repeat until the pointers meet.

2. Same Direction (Parallel Pointers)

In this approach, both pointers start at the same end (usually the beginning) and move in the same direction at different speeds or for different purposes.

0
1
first
1
2
second
2
3
3
4
4
5

These pointers serve two different but complementary roles:

  • the left pointer is the write pointer or boundary, tracking progress and marking where valid elements end.
  • the right pointer is the read or explore pointer, scanning ahead looking for the next element to process.

Template

Here are the two popular variations of this approach:

  • Sliding Window Technique: In this approach, two pointers slide across an array or string while maintaining a dynamic range. It's commonly used to find subarrays or substrings that meet specific criteria, such as:
    • Finding the longest substring without repeating characters
    • or Finding the smallest subarray with a given sum
  • Fast and Slow Pointers: This involves two pointers moving at different speeds. It's commonly used to detect cycles in linked lists or find the middle node of a linked list.

Why Floyd's cycle detection works

The standard speed choice is 1 step for the slow pointer and 2 steps for the fast pointer. If the linked list has a cycle, the slow pointer eventually enters the cycle and starts looping around it. The fast pointer is also looping around the cycle but moves twice as fast.

The relative speed of the fast pointer with respect to the slow pointer is 1 step per iteration: fast advances 2, slow advances 1, and the net difference is 1. Once both pointers are inside the cycle, the fast pointer gains exactly 1 step on slow every iteration. Since the cycle has finite length L, fast catches up to slow within at most L iterations.

If the list has no cycle, the fast pointer reaches the end of the list (null) first. That is the termination condition for the no-cycle case.

To find the starting node of the cycle after detection, reset one pointer to the head and advance both pointers at speed 1. They meet at the cycle's entry node. This is a standard interview follow-up to plain cycle detection.

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

The general same-direction template (read/write partition) also runs in Time: O(n) and Space: O(1), since each pointer advances at most n times across the array.

3. Fixed-Offset Pointers (Same Direction)

This is a specific same-direction pattern, not a separate variant. Both pointers move in the same direction, but one is advanced first to create a fixed gap between them before they move together.

In this approach, we move the first pointer independently until it finds an element that meets a certain condition. After this, we start traversing with the second pointer to find additional information related to what the first pointer found.

The pattern applies when we need to process elements in stages or maintain a fixed distance between two pointers.

Template

A good example of this approach is finding the Nth node from the end of a linked list.

  • Initialize both pointers (fast and slow) at the head.
  • Advance the fast pointer n steps.
  • Then move both pointers one step at a time until the fast pointer reaches the end.
  • The slow pointer is now at the Nth node from the end.

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

When to use two pointers pattern?

A Two-Pointer algorithm is generally applied to linear data structures, such as: array, strings or linked lists.

Two pointers fits problems where the input data follows a predictable pattern, such as a sorted array or palindromic string. Common patterns include:

1. Sorted array with pair/triplet finding

If the array is sorted (or can be sorted) and you need to find elements that satisfy some relationship, two pointers can often replace nested loops.

2. In-place array modification

When you need to modify an array without using extra space, the read-write pointer pattern works well.

3. Palindrome or symmetry checking

Comparing elements from both ends leads to two pointers converging.

4. Merging or comparing sorted sequences

When working with two sorted arrays, using a pointer for each is the natural approach.

5. Subarray problems with monotonic conditions

If expanding a window changes a condition in a predictable direction, two pointers can work. This overlaps with sliding window, which is two pointers with specific semantics.

Scroll
Problem TypeVariantExample
Find pair with target sumOpposite directionTwo Sum II (sorted array)
Check palindromeOpposite directionValid Palindrome
Remove duplicatesSame directionRemove Duplicates from Sorted Array
Partition arraySame directionMove Zeroes, Sort Colors
Merge sorted arraysTwo arraysMerge Sorted Array
Maximum areaOpposite directionContainer With Most Water

When NOT to use two pointers:

  • Array is not sorted and sorting would change the answer (e.g., need original indices)
  • No monotonic relationship between pointer positions and the condition
  • You need to find all pairs, not just check existence (may still need O(n^2))
  • The problem requires looking at non-contiguous elements in arbitrary combinations

Quiz

Introduction Quiz

10 quizzes