Two Pointers and Sliding Window — Master Cheatsheet for Coding Interviews

Sanjeev SharmaSanjeev Sharma
8 min read

Advertisement

Two Pointers and Sliding Window — Mastery Recap

You have just completed 60 problems covering every two-pointer and sliding window variant that ships in real coding interviews at Google, Meta, Amazon, Microsoft, Apple, Netflix, Uber, and other top companies. This recap is your single-page cheatsheet you can revisit the night before an interview.

Why This Recap Matters

Two pointers and sliding window are the two most weaponized linear-time techniques in interviews. If you can confidently classify a problem as "fixed window", "shrinkable window", "inward two pointer", or "fast/slow pointer", you turn what looks like an O(n^2) brute force into a one-pass O(n) solution. Recruiters consistently rank these patterns as table-stakes for any SDE-2 or above coding round.

Keywords interviewers expect to hear: two pointer technique, sliding window interview, shrinkable window, fixed-size window, fast slow pointer, monotonic deque sliding window, prefix sum trick, and at-most minus at-most-1 pattern.

The Five Core Patterns

1. Fixed-Size Window

Use when the problem fixes a window length k and asks for max/min/avg/count inside that window.

def fixed_window(nums, k):
    window_sum = sum(nums[:k])
    best = window_sum
    for i in range(k, len(nums)):
        window_sum += nums[i] - nums[i - k]
        best = max(best, window_sum)
    return best
var fixedWindow = function(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];
        best = Math.max(best, sum);
    }
    return best;
};

Problems: Max Vowels in Substring, Grumpy Bookstore, Max Avg Subarray.

2. Shrinkable (Variable) Window

Use when the window grows greedily, then shrinks until a constraint holds.

def shrinkable(nums, ok):
    left = best = 0
    state = init()
    for right, x in enumerate(nums):
        add(state, x)
        while not ok(state):
            remove(state, nums[left])
            left += 1
        best = max(best, right - left + 1)
    return best
var shrinkable = function(nums, ok) {
    let left = 0, best = 0;
    const state = init();
    for (let right = 0; right < nums.length; right++) {
        add(state, nums[right]);
        while (!ok(state)) {
            remove(state, nums[left]);
            left++;
        }
        best = Math.max(best, right - left + 1);
    }
    return best;
};

Problems: Longest Substring Without Repeating, Min Size Subarray Sum, Longest Substring with Two Distinct, Fruit Into Baskets.

3. Inward Two Pointer (Sorted)

Use on a sorted array when you target pairs/triplets summing to a value or when computing area.

def inward(arr, target):
    l, r = 0, len(arr) - 1
    while l < r:
        s = arr[l] + arr[r]
        if s == target: return [l, r]
        if s < target: l += 1
        else: r -= 1
    return [-1, -1]
var inward = function(arr, target) {
    let l = 0, r = arr.length - 1;
    while (l < r) {
        const s = arr[l] + arr[r];
        if (s === target) return [l, r];
        if (s < target) l++; else r--;
    }
    return [-1, -1];
};

Problems: Two Sum II, 3Sum, 4Sum, Container With Most Water, Boats to Save People, Trapping Rain Water.

4. Fast and Slow Pointer

Use to detect cycles, find midpoints, or compress arrays in place.

def fast_slow_dedup(nums):
    slow = 0
    for fast in range(len(nums)):
        if fast == 0 or nums[fast] != nums[fast - 1]:
            nums[slow] = nums[fast]
            slow += 1
    return slow
var fastSlowDedup = function(nums) {
    let slow = 0;
    for (let fast = 0; fast < nums.length; fast++) {
        if (fast === 0 || nums[fast] !== nums[fast - 1]) {
            nums[slow++] = nums[fast];
        }
    }
    return slow;
};

Problems: Remove Duplicates, Move Zeroes, Linked List Cycle, Happy Number.

5. At-Most Minus At-Most-1 Trick

Counts subarrays with exactly K of something by computing atMost(K) - atMost(K - 1).

def subarrays_with_exactly_k(nums, k):
    def at_most(k):
        if k < 0: return 0
        l = res = 0
        count = {}
        for r, x in enumerate(nums):
            count[x] = count.get(x, 0) + 1
            while len(count) > k:
                count[nums[l]] -= 1
                if count[nums[l]] == 0: del count[nums[l]]
                l += 1
            res += r - l + 1
        return res
    return at_most(k) - at_most(k - 1)
var subarraysWithExactlyK = function(nums, k) {
    const atMost = (k) => {
        if (k < 0) return 0;
        let l = 0, res = 0;
        const count = new Map();
        for (let r = 0; r < nums.length; r++) {
            count.set(nums[r], (count.get(nums[r]) || 0) + 1);
            while (count.size > k) {
                count.set(nums[l], count.get(nums[l]) - 1);
                if (count.get(nums[l]) === 0) count.delete(nums[l]);
                l++;
            }
            res += r - l + 1;
        }
        return res;
    };
    return atMost(k) - atMost(k - 1);
};

Problems: Subarrays with K Different Integers, Number of Substrings With All Three, Count Nice Subarrays.

Pattern Decision Tree

If the problem mentions...Use...
Fixed length k windowFixed-size sliding window
Longest/shortest with constraintShrinkable variable window
Sorted array + sum targetInward two pointer
Cycle / midpoint / dedup in placeFast and slow pointer
Exactly K of somethingatMost(K) - atMost(K-1)
Max in windowMonotonic deque
Negatives + sum targetPrefix sum + hashmap (not pure window)

MAANG Priority Problem List

These are the highest-yield problems based on real interview reports.

RankProblemPattern
1Longest Substring Without RepeatingShrinkable window
23SumInward two pointer
3Container With Most WaterInward two pointer
4Minimum Window SubstringShrinkable window + counter
5Trapping Rain WaterInward two pointer
6Sliding Window MaximumMonotonic deque
7Subarrays with K Different IntegersatMost trick
8Longest Repeating Char ReplacementShrinkable window
9Permutation in StringFixed window + freq map
10Sort ColorsDutch National Flag

Common Mistakes Across All 60 Problems

  • Forgetting to update the answer after the while-shrink loop, not inside.
  • Using a HashMap when an int array of size 26 (lowercase letters) is enough.
  • Confusing "longest" (use shrinkable max) with "shortest" (use shrinkable min, update inside the while loop).
  • Applying sliding window on arrays with negatives when the constraint is sum

    = k. Sliding window only works when adding elements monotonically changes the constraint. Use prefix sum + monotonic deque instead.

  • Forgetting l &lt; r instead of l &lt;= r for inward two pointer when the problem disallows the same index twice.
  • Off-by-one when counting subarrays: the count contributed by each right is right - left + 1, not right - left.

Interview Tips

  • Say the pattern out loud: "I will use a shrinkable sliding window because we want the longest substring satisfying a monotone constraint."
  • Always announce the invariant you maintain ("the window always satisfies at most k distinct characters").
  • State complexity before coding: O(n) time, O(k) space.
  • For "exactly K" problems, immediately reach for the atMost(K) - atMost(K-1) trick — it almost always works and impresses interviewers.

Follow-up Questions To Practice

  • How do you adapt sliding window when negatives are allowed? (Hint: prefix sum + monotonic deque.)
  • How do you stream sliding window stats over an infinite stream? (Hint: bucket-based approximation or reservoir.)
  • How do you parallelize sliding window across shards? (Hint: overlapping prefix and suffix windows on each shard.)
  • Can you solve Sliding Window Maximum in O(1) amortized per element without a deque? (Hint: monotonic stack of buckets.)
  • How do two pointers extend to 2D grids? (Hint: collapse rows then 1D maximum-rectangle-in-histogram per column pair.)

Key Takeaways

  • Two pointers and sliding window collapse O(n^2) brute forces into one-pass O(n) solutions whenever the constraint is monotone over window growth.
  • Memorize the five core templates: fixed window, shrinkable, inward, fast slow, and atMost-minus-atMost-1. Every interview problem maps to one.
  • The shrinkable template is the highest-yield single pattern in this set — practice it until you can write it from muscle memory.
  • For exactly K problems, reach instinctively for atMost(K) - atMost(K-1) instead of trying to maintain exact-K state directly.
  • For sliding window MAX/MIN, the monotonic deque is the canonical O(n) upgrade over a heap.
  • Sliding window does not work directly on arrays with negative numbers when the constraint is sum-based — fall back to prefix sum + hashmap.
  • Practicing 60 problems by pattern (not by random shuffling) is what turns recognition speed from minutes into seconds during a real interview.

Advertisement

Sanjeev Sharma

Written by

Sanjeev Sharma

Full Stack Engineer · E-mopro

Related reading