Home/Learn/DSA/Two Pointers
dsabeginner

Two Pointers Explained

The two pointers technique uses two indices to traverse a data structure, typically reducing O(n²) nested loops to O(n). It is one of the most frequently tested patterns in coding interviews.

Pattern 1: Opposite Ends

Two pointers start at opposite ends of a sorted array and move toward each other. Used for pair sum, palindrome check, and container problems.

// Two Sum II (sorted array)
function twoSumII(nums: number[], target: number): [number, number] {
  let left = 0, right = nums.length - 1;
  while (left < right) {
    const sum = nums[left] + nums[right];
    if (sum === target) return [left + 1, right + 1];
    else if (sum < target) left++;
    else right--;
  }
  return [-1, -1];
}
// Time: O(n), Space: O(1)

Pattern 2: Same Direction

Both pointers move in the same direction. One pointer leads, the other follows. Used for removing duplicates and partitioning.

// Remove duplicates from sorted array
function removeDuplicates(nums: number[]): number {
  let write = 1;
  for (let read = 1; read < nums.length; read++) {
    if (nums[read] !== nums[read - 1]) {
      nums[write] = nums[read];
      write++;
    }
  }
  return write;
}

Pattern 3: Fast and Slow Pointers

One pointer moves one step, the other moves two steps. Used for cycle detection (Floyd's algorithm) and finding the middle of a linked list.

// Detect cycle in linked list
function hasCycle(head: ListNode | null): boolean {
  let slow = head, fast = head;
  while (fast && fast.next) {
    slow = slow!.next;
    fast = fast.next.next;
    if (slow === fast) return true;
  }
  return false;
}

When to Use Two Pointers

  • The input is sorted (opposite ends pattern).
  • You need to compare elements from different parts of the array.
  • The problem involves pairs, triplets, or subarrays.
  • You need to detect a cycle in a linked list or array.
  • You need to partition an array (e.g., move zeros to end).

Common Mistakes

  • Not sorting first : opposite ends pattern requires sorted input.
  • Off-by-one : when pointers meet (left == right vs left < right), the behavior changes.
  • Using two pointers on non-sorted data : without sorted order, you cannot decide which pointer to move.
  • Confusing with sliding window : two pointers compare individual elements; sliding window maintains a subarray.
  • Not handling duplicates : in problems like 3Sum, skip duplicates to avoid duplicate triplets.

Put it into practice

Ready to practice?

Start a mock interview with AI interviewer Alex. Get instant hiring signal.

Start a Mock Interview →