← System Design Simulator

Two Pointers Visualization for Coding Interviews

By Rahul Kumar · Senior Software Engineer · Updated · Category: Arrays & Strings

Pair-sum, dedupe, reverse — the classic two-pointer pattern, animated.

Concept

Two Pointers is the first pattern to reach for whenever the input is a sorted array, a linked list where you need a slow/fast split, or any scan where a nested O(n^2) loop is really collapsing into two coordinated linear walks. The idea is simple: instead of re-scanning the suffix for every prefix index, keep two cursors that only ever move forward (or one from each end moving inward) and let the sorted order prune the search space. That collapses a brute O(n^2) into O(n) without extra memory, which is why it shows up in 3Sum, container-with-most-water, dedupe-in-place, partitioning, cycle detection, palindrome checks, and merging sorted streams. If you see the words 'sorted', 'pair', 'in-place', or 'without extra space', test a two-pointer sweep first.

Two Pointers — Interactive Simulator

Runs fully client-side in your browser; no sign-up. Or open full screen →

Launch the interactive Two Pointers visualization — animated algorithm, step-through, and live data-structure updates.

How it works

There are two flavors. The opposed flavor seeds a left pointer at 0 and a right pointer at n-1, evaluates the pair (a[left], a[right]) against a target, and then advances exactly one pointer based on which direction would bring the pair closer to the target. Because the array is sorted, moving left forward monotonically increases the sum and moving right backward monotonically decreases it, so you never have to revisit a pair. The same-direction flavor uses a slow write-pointer and a fast read-pointer: fast scans every element, slow only advances when the invariant says 'keep this one'. Dedupe-sorted-in-place is the canonical example; slow ends up pointing one past the last kept element. The loop terminates when left >= right (opposed) or fast == n (same-direction). To avoid O(n^2) regressions, every iteration must move at least one pointer unconditionally, and duplicates must be skipped by advancing past equal neighbors inside the same pass, not by re-entering the outer loop. The pattern also composes: 3Sum fixes the first index with an outer loop and runs an opposed two-pointer sweep on the suffix, turning a naive O(n^3) into O(n^2) with O(1) extra memory beyond the sort.

Implementation

TwoPointers.java
package dsa.twopointers;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public final class TwoPointers {

    // Two-sum on a sorted array: returns 1-indexed pair or {-1,-1}.
    public static int[] twoSumSorted(int[] a, int target) {
        int l = 0, r = a.length - 1;
        while (l < r) {
            int sum = a[l] + a[r];
            if (sum == target) return new int[]{l + 1, r + 1};
            if (sum < target) l++;
            else r--;
        }
        return new int[]{-1, -1};
    }

    // Dedupe sorted array in-place, return new length.
    public static int dedupeSorted(int[] a) {
        if (a.length == 0) return 0;
        int slow = 0;
        for (int fast = 1; fast < a.length; fast++) {
            if (a[fast] != a[slow]) {
                slow++;
                a[slow] = a[fast];
            }
        }
        return slow + 1;
    }

    // Classic 3Sum: all unique triplets that sum to zero.
    public static List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> out = new ArrayList<>();
        for (int i = 0; i < nums.length - 2; i++) {
            if (i > 0 && nums[i] == nums[i - 1]) continue;
            int l = i + 1, r = nums.length - 1, target = -nums[i];
            while (l < r) {
                int sum = nums[l] + nums[r];
                if (sum == target) {
                    out.add(Arrays.asList(nums[i], nums[l], nums[r]));
                    while (l < r && nums[l] == nums[l + 1]) l++;
                    while (l < r && nums[r] == nums[r - 1]) r--;
                    l++; r--;
                } else if (sum < target) l++;
                else r--;
            }
        }
        return out;
    }
}

Complexity

Common pitfalls

Key design decisions & trade-offs

Practice problems

Interview follow-ups

Why it matters

Two Pointers is a core part of the Arrays & Strings toolkit. If you are preparing for a technical interview at a top-tier company or teaching a course, a working visualization is the fastest path from "I read about it" to "I understand it".

Related