Unit 1 · Algorithms · Lesson 7 of 24
Two pointers and sliding windows
Builds on
Step 1: Learn the ideas
- Converging pointers on sorted arrays
- Read and write pointers for in-place filtering
- Three-way partitioning
- Fixed-size windows with incremental state
- Variable-size windows: expand, then shrink while invalid
- Window state: counts, last-seen positions, satisfied-requirement counters
- When windows fail: negative values and non-monotone conditions
- Counting subarrays with the at-most-k decomposition
Why it matters
Brute force over all pairs or all subarrays costs O(n²) or more. Two pointers and sliding windows reach O(n) by never moving an index backwards, but only when you can prove that the candidates you skip cannot be the answer. That proof is what interviewers listen for, and it is the same reasoning you use when processing logs or metric streams with bounded memory.
Core ideas
Pattern: Two pointers. On sorted input, start i at the left end and j at the right. Looking for a pair with a given sum: if a[i] + a[j] is too small, pairing a[i] with anything at or before j is also too small, so i can advance; symmetric logic moves j. Each step eliminates a whole row or column of candidate pairs, so the scan is O(n). Container With Most Water uses the same elimination: the shorter of the two lines cannot form a larger container with any line closer to it, so discard it. 3Sum fixes one element and runs this scan on the rest after sorting, skipping equal values to avoid duplicate triples: O(n²) overall.
Read and write pointers. A slow write index and a fast read index filter in place. Move Zeroes keeps "everything before w is the non-zero output in original order". Sort Colors extends this to four regions (less, equal, unknown, greater) maintained by three indices.
Pattern: Sliding window. For contiguous subarrays or substrings:
left = 0
for right in range(n):
add(a[right])
while not valid():
remove(a[left]); left += 1
best = max(best, right - left + 1) # [left, right] is valid here
Invariant: after the inner loop, [left, right] is the longest valid window ending at right. Both indices only move forward, so the total work is O(n) despite the nested loop. This requires validity to survive shrinking: every sub-window of a valid window must be valid. "At most k distinct characters" and "sum at most S with non-negative values" qualify; sums with negative values do not, and need prefix sums with a hash map or a monotonic deque over prefix sums instead. For "shortest valid window" problems (Minimum Size Subarray Sum, Minimum Window Substring) validity must survive growing instead, and you record the answer inside the shrinking loop while the window is still valid.
Window state. Keep only what validity needs, updated in O(1) per step: a count map plus a counter of satisfied requirements (Minimum Window Substring), last-seen positions (Longest Substring Without Repeating Characters) or a running sum. For Longest Repeating Character Replacement, the window is valid while its length minus its largest single-character count is at most k.
Fixed windows. For windows of exactly k elements, add the entering element and remove the leaving one at each step (Permutation in String, Find All Anagrams in a String).
Exactly k. "Exactly k distinct values" is not preserved by shrinking, but "at most k" is. Count windows with at most k distinct values and subtract those with at most k − 1.
Common misconceptions
- "A loop inside a loop is O(n²)." If each pointer only moves forward, there are at most 2n pointer moves in total.
- "Every subarray-sum problem is a sliding window." Windows need validity that is monotone under shrinking or growing; with negative numbers it is not, so use prefix sums.
- "Converging pointers work on unsorted data." They rely on order; sort first (paying O(n log n)) or use hashing.
- "Either pointer can move." Each move must come with an argument that the skipped candidates cannot be optimal.
- "Record the answer anywhere in the loop." Record where the invariant holds: after shrinking for longest-valid windows, inside the shrinking loop for shortest-valid ones.
How to approach it
Ask first: contiguous or not, sorted or not, can values be negative? Then state the validity condition and why it is monotone, or the elimination argument for converging pointers, before coding. Say what the window state is and how add and remove update it in O(1). Test an empty input, a window that never becomes valid, and all-equal elements. Interviewers typically ask why the scan is linear and what changes when negative numbers are allowed. Build the reflex by asking these questions on unseen problems; recalling specific question lists is not what transfers.
Suggested order
- 1Read Chapter 8.1 (Two pointers method) of the Competitive Programmer’s Handbook for the amortized argument behind two-pointer scans.
- 2Solve Valid Palindrome and Two Sum II - Input Array Is Sorted, writing the elimination argument for each pointer move.
- 3Solve Container With Most Water and 3Sum, including duplicate skipping without a set.
- 4Solve Longest Substring Without Repeating Characters and Minimum Size Subarray Sum, noting where each records its answer.
- 5Solve Permutation in String with a fixed window and Longest Repeating Character Replacement with a variable one.
- 6Solve Minimum Window Substring using a satisfied-requirements counter.
- 7Solve Subarrays with K Different Integers with the at-most-k decomposition, then revisit two problems from the LeetCode 75 or Top Interview 150 two-pointer and window sections that you have not seen.
Step 2: Check off what you can do
Tap each one you can genuinely do or explain. Each earns 10 XP.
Step 3: Go deeper
Competitive Programmer’s Handbook: search, amortized-analysis, range-query and trie sectionsStart here
CSESSection: Ch. 8: Amortized analysis (8.1 Two pointers method)
Two-pointer scans explained with the argument that makes them linear, in a few pages.
Open(opens in a new tab)Link responded, 5 Oct 2026LeetCode 75 study plan
LeetCodeIts two-pointer and sliding-window problems give a first practice pass after reading the notes.
Open(opens in a new tab)Not checkable automatically, 5 Oct 2026LeetCode Top Interview 150 study plan
LeetCodeMore two-pointer and sliding-window problems for review rotation with unseen problems.
Open(opens in a new tab)Not checkable automatically, 5 Oct 2026
Step 4: Practice
Before coding, write one sentence for the invariant: the elimination argument for converging pointers, or the validity condition and why it is monotone for windows. Count pointer moves to justify O(n). Minimum Size Subarray Sum and Minimum Window Substring record the answer inside the shrinking loop; the longest-window problems record it after. Subarrays with K Different Integers checks the at-most-k decomposition and is a good review problem.
- Valid PalindromeLeetCode(opens in a new tab)Not attemptedLeetCode
- Two Sum II - Input Array Is SortedLeetCode(opens in a new tab)Not attemptedLeetCode
- Container With Most WaterLeetCode(opens in a new tab)Not attemptedLeetCode
- 3SumLeetCode(opens in a new tab)Not attemptedLeetCode
- Longest Substring Without Repeating CharactersLeetCode(opens in a new tab)Not attemptedLeetCode
- Minimum Size Subarray SumLeetCode(opens in a new tab)Not attemptedLeetCode
- Permutation in StringLeetCode(opens in a new tab)Not attemptedLeetCode
- Longest Repeating Character ReplacementLeetCode(opens in a new tab)Not attemptedLeetCode
- Minimum Window SubstringLeetCode(opens in a new tab)Not attemptedLeetCode
- Subarrays with K Different IntegersLeetCode(opens in a new tab)Not attemptedLeetCode
- Best Time to Buy and Sell StockLeetCode(opens in a new tab)Not attemptedLeetCode
- Find All Anagrams in a StringLeetCode(opens in a new tab)Not attemptedLeetCode
- Longest Continuous Subarray With Absolute Diff Less Than or Equal to LimitLeetCode(opens in a new tab)Not attemptedLeetCode
- Longest Palindromic SubstringLeetCode(opens in a new tab)Not attemptedLeetCode
- Move ZeroesLeetCode(opens in a new tab)Not attemptedLeetCode
- Sort ColorsLeetCode(opens in a new tab)Not attemptedLeetCode
- Trapping Rain WaterLeetCode(opens in a new tab)Not attemptedLeetCode
- LeetCode 75 (official study plan)LeetCode(opens in a new tab)Not attemptedLeetCode
Record attempts on each problem’s page (+15 XP, +10 more when solved on your own).
Step 5: Test yourself
Answer each one out loud or on paper before you finish the lesson.
- Question 1What property must the validity condition have for a variable window to be correct?
- Question 2Why is a window with a nested while loop still O(n)?
- Question 3Where do you record the answer for longest-valid versus shortest-valid windows?
- Question 4How do you avoid duplicate triples in 3Sum without a set?
- Question 5How do you count subarrays with exactly k distinct values using windows?
You’re done when you can
- Solve two unseen sliding-window problems in under 25 minutes each, stating the validity condition and why it is monotone.
- Explain why the pointer move in Container With Most Water cannot skip the optimum.
- Explain why a sliding window fails for subarray sums with negative numbers, and name the replacement technique.
- Solve Minimum Window Substring in under 35 minutes without hints.
Finish the lesson
Unlocks next: Monotonic stacks and deques, Pattern recognition and mixed practice


