Two Pointers & Sliding Window — Complete Guide (Problems 101–160)
Advertisement
Series Introduction
Welcome to the Two Pointers & Sliding Window series — the second chapter of our MAANG DSA Roadmap. This section covers 60 problems (#101–#160) grouped by pattern, from easy warm-ups to Google Hard problems.
Previous Series: Arrays & Strings (Problems 1–100)
Why Two Pointers & Sliding Window?
These are among the most asked patterns at FAANG/MAANG. They convert naive O(n²) brute-force solutions into clean O(n) algorithms by maintaining a structure that avoids redundant work.
| Pattern | Core Idea | Typical Complexity |
|---|---|---|
| Fixed Window | Slide a window of size k | O(n) |
| Variable Window | Shrink/expand based on condition | O(n) |
| Two Pointers (opposite ends) | Meet in middle | O(n) |
| Two Pointers (same direction) | Fast/slow or read/write | O(n) |
| at-most(k) − at-most(k−1) | Count "exactly k" | O(n) |
| Prefix Sum + Deque | Handle negatives | O(n) |
The Mental Model
Fixed Window:
[l -------- r] → slide right, always size k
Sum: s += a[r] - a[r-k]
Variable Window (expand-then-shrink):
l=0
for r in range(n):
add a[r] to window
while window invalid:
remove a[l], l++
ans = max(ans, r-l+1)
Two Pointers — Inward:
l=0, r=n-1
while l < r:
if condition: l++
else: r--
Two Pointers — Same Direction (read/write):
write=0
for read in range(n):
if keep(a[read]):
a[write++] = a[read]
Problem Index
🟢 Easy (101–110)
| # | Problem | Pattern | Difficulty |
|---|---|---|---|
| 101 | Valid Palindrome | Two Ptr Inward | Easy |
| 102 | Reverse String | Two Ptr Swap | Easy |
| 103 | Squares of Sorted Array | Two Ptr L/R | Easy |
| 104 | Remove Element | Read/Write Ptr | Easy |
| 105 | Remove Duplicates (Sorted) | Write Ptr | Easy |
| 106 | Merge Sorted Arrays | 3-Ptr from End | Easy |
| 107 | Is Subsequence | Two Ptr | Easy |
| 108 | Max Consecutive Ones III | Sliding Window | Easy |
| 109 | Diet Plan Performance | Fixed Window | Easy |
| 110 | Running Sum 1D | Prefix Sum | Easy |
🟡 Medium (111–150)
| # | Problem | Pattern | Difficulty |
|---|---|---|---|
| 111 | Longest Substring Without Repeating | Variable Window | Medium |
| 112 | Longest Repeating Char Replacement | Window + Freq | Medium |
| 113 | Permutation in String | Fixed Window | Medium |
| 114 | Fruit Into Baskets | K-Distinct Window | Medium |
| 115 | Max Erasure Value | HashSet Window | Medium |
| 116 | Minimum Size Subarray Sum | Variable Window | Medium |
| 117 | Subarrays Size K & Avg≥Threshold | Fixed Window | Medium |
| 118 | Count Subarrays Max=K | Counting Window | Medium |
| 119 | 4Sum II | Two Sum on Halves | Medium |
| 120 | 3Sum | Sort + Two Ptr | Medium |
| 121 | Two Sum II (Sorted) | Two Ptr | Medium |
| 122 | Container with Most Water | Greedy Two Ptr | Medium |
| 123 | Boats to Save People | Greedy Two Ptr | Medium |
| 124 | Partition Labels | Two Ptr + Last Occ | Medium |
| 125 | Subarray Product Less Than K | Sliding Window | Medium |
| 126 | Max Points from Cards | Fixed Window (n-k) | Medium |
| 127 | Min Ops to Reduce X to Zero | Longest Mid Subarray | Medium |
| 128 | Count Nice Subarrays | At-Most Trick | Medium |
| 129 | Binary Subarrays with Sum | At-Most Trick | Medium |
| 130 | Subarrays K Different Integers | Exactly-K Window | Medium |
| 131 | Frequency of Most Frequent Element | Sorted + Window | Medium |
| 132 | Replace Substring Balanced String | Two Ptr | Medium |
| 133 | Longest Subarray of 1s Deleting One | Variable Window | Medium |
| 134 | Min Flips for Alternating Binary | Sliding Window | Medium |
| 135 | Take K of Each Character | Window Max Middle | Medium |
| 136 | Max Vowels in Substring of Len K | Fixed Window | Medium |
| 137 | Grumpy Bookstore Owner | Fixed Window Bonus | Medium |
| 138 | Min Swaps to Group 1s Together | Fixed Window | Medium |
| 139 | Longest Mountain in Array | Two Ptr Expand | Medium |
| 140 | Longest Turbulent Subarray | Two Ptr/DP | Medium |
| 141 | Min Diff Highest-Lowest K Scores | Sorted Window | Medium |
| 142 | Get Equal Substrings Within Budget | Sliding Window | Medium |
| 143 | Subarrays with All Three Chars | Three Ptr | Medium |
| 144 | Subarray Sum Divisible by K | Prefix + Modulo | Medium |
| 145 | Find K Closest Elements | Binary Search + Two Ptr | Medium |
| 146 | Sort Vowels in a String | Two Ptr | Medium |
| 147 | Count Subarrays with Fixed Bounds | Sliding Window | Medium |
| 148 | Max Consecutive Ones (Flip) | Variable Window | Medium |
| 149 | Sliding Window Median | Two Heaps | Hard+ |
| 150 | Number of Substrings with All 3 Chars | Three Ptr | Medium |
🔴 Hard (151–160)
| # | Problem | Pattern | Difficulty |
|---|---|---|---|
| 151 | Minimum Window Substring | have/need Counter | Hard |
| 152 | Sliding Window Maximum | Monotonic Deque | Hard |
| 153 | Shortest Subarray Sum≥K | Deque on Prefix | Hard |
| 154 | Minimum Window Subsequence | Two Ptr DP | Hard |
| 155 | Count Subarrays Median=K | Prefix Balance | Hard |
| 156 | Longest Substring Two Distinct | Variable Window | Hard |
| 157 | Substring Concatenation All Words | Multi-Window | Hard |
| 158 | Min Consecutive Cards to Pick Up | HashMap Window | Hard |
| 159 | Count Subarrays Score < K | Two Ptr | Hard |
| 160 | Two Pointers & Sliding Window Recap | All Patterns | Summary |
Core Template Cheatsheet
# Fixed Window
def fixed_window(nums, k):
s = sum(nums[:k])
best = s
for i in range(k, len(nums)):
s += nums[i] - nums[i-k]
best = max(best, s)
return best
# Variable Window (shrink when invalid)
def variable_window(nums, condition):
left = best = 0
window_state = initial_state()
for right, val in enumerate(nums):
add(val, window_state)
while not valid(window_state):
remove(nums[left], window_state)
left += 1
best = max(best, right - left + 1)
return best
# Exactly K = atMost(K) - atMost(K-1)
def exactly_k(nums, k):
return at_most(nums, k) - at_most(nums, k-1)
# Two Pointer Inward
def two_pointer(arr):
l, r = 0, len(arr) - 1
while l < r:
if condition(arr[l], arr[r]): l += 1
else: r -= 1
Next in Series
Advertisement