Two pointers and sliding window: patterns with examples

Two pointers and sliding windows turn O(n²) array and string problems into O(n). Learn when and how to use each.

Two pointers moving across an array and a window sliding along it

Many array and string problems ask about subarrays, substrings or pairs. A brute-force solution checks all possibilities in O(n²) or worse. Two techniques often cut that to O(n): two pointers and the sliding window.

Technique 1: two pointers

Use two indexes that move through the data to avoid nested loops. There are two common shapes.

Opposite ends, moving inward

Works well on sorted arrays or when checking symmetry.

Problem: in a sorted array, find two numbers that add up to a target.

function twoSumSorted(nums, target) {
  let left = 0, right = nums.length - 1;
  while (left < right) {
    const sum = nums[left] + nums[right];
    if (sum === target) return [left, right];
    if (sum < target) left++;      // need a bigger sum
    else right--;                  // need a smaller sum
  }
  return [];
}
// Time O(n), space O(1)

Because the array is sorted, each step safely discards one candidate. That is why it works.

Problem: is a string a palindrome (ignoring non-letters)? Compare from both ends, moving inward.

Other uses: the container with most water, 3Sum (sort, fix one number, then two pointers on the rest), reversing in place.

Same direction: slow and fast

Both pointers move forward at different paces or roles.

Problem: remove duplicates from a sorted array in place.

function removeDuplicates(nums) {
  if (nums.length === 0) return 0;
  let write = 1;
  for (let read = 1; read < nums.length; read++) {
    if (nums[read] !== nums[read - 1]) nums[write++] = nums[read];
  }
  return write;     // length of the unique part
}
// Time O(n), space O(1)

The read pointer scans; the write pointer marks where the next kept value goes. The same idea moves zeroes to the end or filters values.

Fast and slow on linked lists: moving one pointer twice as fast finds the middle, and detects a cycle (Floyd's algorithm).

Technique 2: sliding window

A window is a contiguous range of the array or string. You slide it by adding the new element on the right and removing the old one on the left, updating a running value instead of recomputing everything.

Fixed-size window

Problem: the maximum sum of any subarray of size k.

function maxSumK(nums, k) {
  let sum = 0;
  for (let i = 0; i < k; i++) sum += nums[i];
  let best = sum;
  for (let i = k; i < nums.length; i++) {
    sum += nums[i] - nums[i - k];     // add the new, drop the old
    best = Math.max(best, sum);
  }
  return best;
}
// Time O(n), space O(1)

Variable-size window

The window expands on the right, and shrinks from the left whenever a rule is broken.

Problem: the length of the longest substring without repeating characters.

function longestUnique(s) {
  const lastSeen = new Map();
  let left = 0, best = 0;
  for (let right = 0; right < s.length; right++) {
    const ch = s[right];
    if (lastSeen.has(ch) && lastSeen.get(ch) >= left) {
      left = lastSeen.get(ch) + 1;       // jump past the repeat
    }
    lastSeen.set(ch, right);
    best = Math.max(best, right - left + 1);
  }
  return best;
}
// Time O(n), space O(min(n, alphabet))

A general template for variable windows:

left = 0
for right in range(n):
    add item[right] to window state
    while window is invalid:
        remove item[left] from window state
        left += 1
    update the answer using the window [left..right]

More problems: smallest subarray with sum at least S (positive numbers), longest substring with at most K distinct characters, minimum window substring, permutation in string.

When to use which

Clue in the problem Likely technique
Sorted array, find a pair or triplet Two pointers from both ends
In-place modification, remove or partition Read/write pointers
Linked list middle or cycle Fast and slow pointers
Contiguous subarray or substring, with a size or a condition Sliding window
Subarray sum with possibly negative numbers Prefix sums + hash map (window can fail)

Sliding window with a shrinking rule relies on a monotonic condition: adding elements keeps moving the window state in one direction. With negative numbers that can break.

Common mistakes

  • Off-by-one errors at the window edges. Decide whether right is inclusive and test small cases by hand.
  • Forgetting to update the window state when moving left.
  • Using a window when the data are not contiguous (then think hash map, DP or sorting).
  • Not handling empty input, or k larger than the array.

Practice problems

Valid Palindrome, Two Sum II (sorted), 3Sum, Container With Most Water, Remove Duplicates from Sorted Array, Best Time to Buy and Sell Stock, Longest Substring Without Repeating Characters, Minimum Window Substring.

Takeaway: if a problem asks about pairs in sorted data or contiguous ranges, try two pointers or a sliding window. Both aim to visit each element a constant number of times, giving O(n).


Interview prep and DSA series, Part 1 (core patterns): 3 of 5. Previous: Arrays and hash maps: the interview patterns you must know.

Keep reading