Two Pointers & Sliding Windows: Elegance in O(n)

Faiaz KhanFaiaz Khan
4 min read

Imagine going through a list once and solving a problem that would otherwise need nested loops and a prayer.

That’s the magic of Two Pointers and Sliding Windows — algorithms that give you O(n) time for problems that feel like they should be O(n²).

If you're still looping through every substring like it's 2015, this one's for you.


🧠 What Are Two Pointers?

Two Pointers = Literally using two variables (often left and right) to traverse data efficiently.

They work when:

  • Your data is linear (arrays, strings)

  • The problem involves comparison, matching, or scanning ranges

  • You want to avoid unnecessary rework or overlap


🪟 Sliding Window = Two Pointers + Constraint

A sliding window is a specific case where:

  • You're looking at a "window" of elements (contiguous)

  • You grow/shrink the window as you move across the array

  • You keep track of something: sum, frequency, length, etc.

Think of it like a moving camera on an array.
Instead of recording every moment, you just adjust the lens.


🤯 Why Use These?

FeatureBenefit
One passO(n) runtime
In-place traversalO(1) extra space (often)
Real-world friendlyStreaming, memory, search stuff
Interviewer friendly“Oh wow, you optimized that? 😳”

🔥 Problem 1: Longest Substring Without Repeating Characters

Given a string, return the length of the longest substring without repeating characters.

❌ Brute-force

Check every substring.
Time: O(n²).
Tears: infinite.

✅ Sliding Window

function lengthOfLongestSubstring(s) {
  let map = new Map();
  let left = 0, maxLen = 0;

  for (let right = 0; right < s.length; right++) {
    if (map.has(s[right])) {
      left = Math.max(map.get(s[right]) + 1, left);
    }
    map.set(s[right], right);
    maxLen = Math.max(maxLen, right - left + 1);
  }

  return maxLen;
}
  • The left pointer jumps past duplicates

  • The right pointer keeps expanding

  • Result: smooth substring gliding in O(n)


🍟 Problem 2: Minimum Size Subarray Sum

Given an array of positive integers and a target, return the minimum length of a subarray whose sum is ≥ target.

function minSubArrayLen(target, nums) {
  let sum = 0, left = 0, minLen = Infinity;

  for (let right = 0; right < nums.length; right++) {
    sum += nums[right];

    while (sum >= target) {
      minLen = Math.min(minLen, right - left + 1);
      sum -= nums[left++];
    }
  }

  return minLen === Infinity ? 0 : minLen;
}

You just:

  • Kept a window of elements

  • Moved right to expand

  • Moved left to shrink

  • Maintained constraint: sum >= target

That’s the sliding window in action.


👀 Problem 3: Check If Array Has Two Elements That Sum to Target (Sorted)

Given a sorted array, does any pair sum to a target?

function hasPairWithSum(nums, target) {
  let left = 0, right = nums.length - 1;

  while (left < right) {
    const sum = nums[left] + nums[right];
    if (sum === target) return true;
    if (sum < target) left++;
    else right--;
  }

  return false;
}

Two pointers:

  • One from start

  • One from end

  • Narrowing based on sum comparison

Elegant. Sorted. Efficient.


🧮 Problem 4: Container With Most Water

Given heights, find max water two lines can trap.

function maxArea(height) {
  let left = 0, right = height.length - 1;
  let maxArea = 0;

  while (left < right) {
    const h = Math.min(height[left], height[right]);
    const w = right - left;
    maxArea = Math.max(maxArea, h * w);

    if (height[left] < height[right]) left++;
    else right--;
  }

  return maxArea;
}
  • We reduce the smaller height

  • Try to expand the area

  • Achieves max with one pass


🧠 Recap: When to Use What?

Problem TypeTechnique
Substrings/Subarrays with constraintSliding Window
Sorted Array + Pairwise LogicTwo Pointers
Max/Min in contiguous blockSliding Window
Range Scan with Jumping IndexesTwo Pointers

🪄 Real-World Analogies

  • Two Pointers: You're at both ends of a hallway, walking toward the truth

  • Sliding Window: You're trying to hold the perfect amount of popcorn in a leaky bag

  • Brute Force: You’re checking every house on the block for your lost AirPods.

  • Two Pointers: You AirDrop ping both ends of the street and narrow it down.


🚫 Common Mistakes

❌ Resetting left incorrectly
❌ Forgetting to shrink the window
❌ Not updating max/min values inside loops
❌ Assuming all problems fit sliding windows

✨ Tip: Always draw out the index movements if confused.


🧵 Final Thoughts

Two pointers and sliding window aren’t just space-savers.
They’re mental models — ways to traverse time, memory and constraints intelligently.

Brute force loops? Outdated.

Smart traversal? That’s you now.

So next time someone says,

"Try every possible pair..."
You say: "Nah. I’ll just slide into O(n) real quick."


📚 Want more creative DSA goodness?

Follow Code Like You Mean It — DSA Edition for more.

Until then — keep your windows sliding, your pointers tight, and your runtime clean,
Peace ✌️

0
Subscribe to my newsletter

Read articles from Faiaz Khan directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Faiaz Khan
Faiaz Khan

Hey! I'm Faiaz — a frontend developer who loves writing clean, efficient, and readable code (and sometimes slightly chaotic code, but only when debugging). This blog is my little corner of the internet where I share what I learn about React, JavaScript, modern web tools, and building better user experiences. When I'm not coding, I'm probably refactoring my to-do list or explaining closures to my cat. Thanks for stopping by — hope you find something useful or mildly entertaining here.