DSA · Topic 2 of 18 · Core Structures

Two Pointers

Sorted? Start at both ends and walk inwards — each move throws away an impossible answer.

5 problems · O(n) (O(n log n) if you must sort first) time, O(1) space

Step 1 Understand it

Remember it by

Sorted? Start at both ends and walk inwards — each move throws away an impossible answer.

Watch it happen

AnimationTwo pointers: start at both ends, and each step rules out an answer
Read the animation as text
  1. The array is sorted. Put L on the smallest number and R on the largest.
  2. 1 + 11 = 12: too big. L already holds the smallest number left, so 11 is too big with every partner. Drop it: move R left.
  3. 1 + 8 = 9: too small. R already holds the largest number left, so 1 is too small with every partner. Drop it: move L right.
  4. 2 + 8 = 10. Answer (1-indexed): [2, 5]. Each step threw away a number that could never be in the answer, so it is one pass and O(1) space.

The idea

Two indexes move through the data at the same time, usually one from each end. Each comparison tells you which pointer can move, so you rule out many answers per step and finish in one pass.

Picture it

flowchart LR
  L["L →"] --- A["sorted array"] --- R["← R"]
  A --> Q{"compare arr[L] and arr[R]"}
  Q -->|"too small"| ML["move L right"]
  Q -->|"too big"| MR["move R left"]
  Q -->|"just right"| D["answer ✓"]
Every comparison lets one pointer move, ruling out answers that can't work.

Analogy

Finding two friends whose heights add to 3 metres in a line sorted by height. Too short in total? Swap the shortest for the next one up. Too tall? Swap the tallest for the next one down.

Where the analogy breaks

With friends you could just look around. The trick only works because the order is known: moving a pointer is safe only when sorting guarantees everything you skip is worse.

More detail

What it is

Imagine you and a friend are searching a library. Instead of you searching the whole library alone, you start at the front door, and your friend starts at the back door. You walk towards each other until you meet in the middle. That's the Two Pointer technique! It's a strategy where you use two variables (pointers) to iterate through an array or string simultaneously, usually from opposite ends or moving at different speeds.

When to use it

  • When dealing with sorted arrays or string palindromes.
  • When searching for pairs that sum up to a target (if sorted).
  • When reversing an array or string completely in-place.

How it works

You initialize a left pointer at index 0, and a right pointer at the last index. You run a while (left < right) loop. Depending on the condition, you either move the left pointer forward left++ or the right pointer backward right-- until they meet.

Example walkthrough

Input: s = "racecar"

  1. left='r', right='r'. They match. Move pointers inward (left++, right--).
  2. left='a', right='a'. They match. Move inward.
  3. left='c', right='c'. They match.
  4. left and right cross paths at 'e'. It's a valid Palindrome!

Result: true

Related patterns

  • Sliding Window: A variation of Two Pointers where the pointers move in the same direction.

Step 2 Recognise it

Words that signal it

  • The input is sorted (or sorting it is allowed)
  • 'Pair / triplet that sums to…' in a sorted array
  • 'Palindrome', 'reverse in place'
  • 'Container', 'trapping water' — two walls that limit each other
  • They ask for O(1) extra space

Don't confuse it with

  • Sliding Window: Window = a contiguous range where both pointers move the same way. Two pointers here = opposite ends moving towards each other.
  • Arrays & Hashing: Unsorted and you can't sort (you need original indexes)? Use a hash map instead.

Gut check

Sorted, and I'm comparing a pair from both ends? → two pointers.

How to recognise it in an interview

The array is explicitly SORTED, or you need to find a combination of elements at opposite ends.

Step 3 The template

The general shape. Adapt it to each problem rather than learning one solution per problem.

python
def solve(arr):
    left, right = 0, len(arr) - 1
    while left < right:
        if ...:            # found what you want
            return ...
        elif ...:          # left side too small / worse
            left += 1
        else:              # right side too big / worse
            right -= 1
    return ...
The same template in Java
text
class Solution {
    public boolean isPalindrome(String s) {
        int left = 0, right = s.length() - 1;
        while (left < right) {
            if (s.charAt(left) != s.charAt(right)) {
                return false;
            }
            left++;
            right--;
        }
        return true;
    }
}
TimeO(n) (O(n log n) if you must sort first)
SpaceO(1)

Common mistakes

  • Using left <= right when the two pointers must be different items (it should be left < right).
  • In 3Sum, not skipping repeated values, so the same triplet appears twice.
  • Moving the wrong pointer in Container With Most Water: always move the shorter wall, because the taller one can't help while the shorter one limits the height.
  • Forgetting to actually increment or decrement the pointers inside the loop, causing an infinite loop crash!

Step 4 Watch it run

Two problems, traced step by step exactly as the code runs.

Easy example: Two Sum II (sorted input)

Input: numbers = [1, 2, 4, 6, 8, 11], target = 10

LRsumaction
051 + 11 = 12too big → move R left
041 + 8 = 9too small → move L right
142 + 8 = 10found it

Result: [2, 5]

Notice: When the sum is too big, L already holds the smallest number left, so R is too big with every partner. R can never be in the answer — move it.

python
def two_sum_sorted(numbers, target):
    left, right = 0, len(numbers) - 1
    while left < right:
        total = numbers[left] + numbers[right]
        if total == target:
            return [left + 1, right + 1]      # 1-indexed answer
        if total < target:
            left += 1
        else:
            right -= 1
    return []

Medium example: Container With Most Water

Input: height = [1, 8, 6, 2, 5, 4, 8, 3, 7]

LRareabestmove
0 (h=1)8 (h=7)min(1, 7) × 8 = 88move L (shorter)
1 (h=8)8 (h=7)min(8, 7) × 7 = 4949move R (shorter or equal)
1 (h=8)7 (h=3)min(8, 3) × 6 = 1849move R (shorter or equal)
1 (h=8)6 (h=8)min(8, 8) × 5 = 4049move R (shorter or equal)
1 (h=8)5 (h=4)min(8, 4) × 4 = 1649move R (shorter or equal)
1 (h=8)4 (h=5)min(8, 5) × 3 = 1549move R (shorter or equal)
1 (h=8)3 (h=2)min(8, 2) × 2 = 449move R (shorter or equal)
1 (h=8)2 (h=6)min(8, 6) × 1 = 649move R (shorter or equal)

Result: 49

Notice: The shorter wall decides the height. Moving the taller wall can only shrink the width without raising the height, so always move the shorter one.

python
def max_area(height):
    left, right = 0, len(height) - 1
    best = 0
    while left < right:
        area = min(height[left], height[right]) * (right - left)
        best = max(best, area)
        if height[left] < height[right]:
            left += 1
        else:
            right -= 1
    return best

Step 5 Practise

Read each question and say the pattern and the trick out loud before you open the answer. Then solve it on LeetCode. Tick a problem once you've solved it on your own: it comes back for review tomorrow, then after 3, 7, 14 and 30 days, then every month, on the DSA page.

Easy

  1. Valid Palindrome Easy

    Decide whether a string reads the same forwards and backwards, ignoring case and non-letters.

    Show answer

    Technique: Two pointers from both ends

    The clue: 'Palindrome' = compare the two ends moving inwards.

    The trick: Skip non-alphanumeric characters with each pointer, compare lower-case letters, move both inwards.

Medium

  1. Two Sum II Input Array Is Sorted Medium

    In a sorted array, find the two numbers that add up to a target, using constant extra space.

    Show answer

    Technique: Two pointers from both ends

    The clue: Sorted + a pair + O(1) space.

    The trick: Sum too small → move the left pointer right; too big → move the right pointer left.

  2. 3Sum Medium

    Find all unique triplets that add up to zero.

    Show answer

    Technique: Sort + fix one + two pointers

    The clue: A triplet sum is a pair sum (Two Sum II) for every fixed first number.

    The trick: Sort; for each i, run two pointers on the rest for −nums[i]; skip equal neighbours to avoid duplicate triplets.

  3. Container With Most Water Medium

    Pick two vertical lines that, with the x-axis, hold the most water.

    Show answer

    Technique: Two pointers, move the shorter wall

    The clue: Two walls limit each other: area = shorter height × distance.

    The trick: Start at both ends and always move the shorter wall; moving the taller one can never help.

Hard

  1. Trapping Rain Water Hard

    Given bar heights, compute how much rain water is trapped between them.

    Show answer

    Technique: Two pointers with left max and right max

    The clue: Water above a bar depends on the tallest bar on each side.

    The trick: Water at i = min(max left, max right) − height[i]; move the side with the smaller max, since that side is the limit.

What to say in the interview

'Since the array is sorted, we can avoid O(N) extra space by using two pointers from opposite ends.'

Follow-up prep

What if there are duplicates in the sorted array? (You might have to skip them).