Two Pointers and Sliding Window — Master Cheatsheet for Coding Interviews
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 bestvar 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 bestvar 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 slowvar 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 window | Fixed-size sliding window |
| Longest/shortest with constraint | Shrinkable variable window |
| Sorted array + sum target | Inward two pointer |
| Cycle / midpoint / dedup in place | Fast and slow pointer |
| Exactly K of something | atMost(K) - atMost(K-1) |
| Max in window | Monotonic deque |
| Negatives + sum target | Prefix sum + hashmap (not pure window) |
MAANG Priority Problem List
These are the highest-yield problems based on real interview reports.
| Rank | Problem | Pattern |
|---|---|---|
| 1 | Longest Substring Without Repeating | Shrinkable window |
| 2 | 3Sum | Inward two pointer |
| 3 | Container With Most Water | Inward two pointer |
| 4 | Minimum Window Substring | Shrinkable window + counter |
| 5 | Trapping Rain Water | Inward two pointer |
| 6 | Sliding Window Maximum | Monotonic deque |
| 7 | Subarrays with K Different Integers | atMost trick |
| 8 | Longest Repeating Char Replacement | Shrinkable window |
| 9 | Permutation in String | Fixed window + freq map |
| 10 | Sort Colors | Dutch 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 < rinstead ofl <= rfor 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, notright - 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