Documentation Index
Fetch the complete documentation index at: https://resources.devweekends.com/llms.txt
Use this file to discover all available pages before exploring further.
Two Pointers & Sliding Window
The Mental Model
Imagine you are adjusting a rubber band stretched between two fingers on a number line. You can stretch it wider by moving your right finger forward, or shrink it by sliding your left finger forward. The critical insight is that neither finger ever moves backwards. Each finger visits each position at most once, so the total work is O(n) + O(n) = O(n), even though it looks like a nested loop. Compare this to the brute force approach, where you would try every possible left position with every possible right position---that is O(n^2) pairs. Two pointers exploit the monotonic structure of the problem to skip the vast majority of those pairs.Pattern Recognition Signals:
- “Find pair/triplet with property X”
- “Subarray with sum/length condition”
- Array is sorted or can be sorted
- Need to avoid O(n²) nested loops
When to Use Two Pointers
Use When
- Sorted array + finding pairs
- Subarray with sum/length constraints
- Palindrome checking
- Merging sorted arrays
- Removing duplicates in-place
Don't Use When
- Need to preserve original order
- No monotonic property exists
- Need random access queries
- Prefix sum is more natural
The Two Pointer Variants
Variant 1: Opposite Ends (Converging)
Use for: Sorted arrays, finding pairs with target sum, palindromes.Variant 2: Same Direction (Fast & Slow)
Use for: Removing duplicates, cycle detection, partitioning.Variant 3: Sliding Window
Use for: Subarray with sum/product condition, longest/shortest subarray.Pattern Recognition: Sliding Window Types
Fixed-Size Window
Signal: “Find max/min/count in every window of size K”Variable-Size Window
Signal: “Find longest/shortest subarray where condition holds”- Window grows: “a”, “aa”, “aab”, “aaba”, “aabac” (3 distinct: a,b,c)
- Adding ‘b’: “aabacb” still 3 distinct, fine
- Adding ‘e’: “aabacbe” has 4 distinct, must shrink from left
- Remove ‘a’,‘a’,‘b’,‘a’,‘c’ until distinct count drops to 3
- Continue expanding from right…
- Answer: “cbebebe” with length 7
The “When to Shrink” Framework
For sliding window, the key question is: when do I move the left pointer?| Problem Type | Shrink When |
|---|---|
| Sum ≥ target (minimum length) | Window sum ≥ target |
| Sum ≤ target (maximum length) | Window sum > target |
| At most K distinct | More than K distinct |
| No duplicates | Duplicate found |
Classic Problems & Solutions
Three Sum (CF Pattern)
Problem: Find all triplets that sum to zero. Approach: Fix one element, use two pointers for the remaining two.Container With Most Water
Problem: Given heights, find two lines that form container with most water. Insight: Start from ends. The limiting factor is the shorter line. Moving the shorter line might find a taller one; moving the taller can’t help.Common Mistakes
Practice Problems
Beginner (800-1100)
Intermediate (1100-1400)
Advanced (1400-1700)
Decision Flowchart
Key Takeaways
Monotonic Property
Two pointers work when moving in one direction doesn’t require backtracking.
Shrink vs Expand
For minimum → shrink while valid. For maximum → shrink while invalid.
Sort First
Many two-pointer problems require sorted input. Don’t forget to sort.
Track State
Use hashmap/set to track window contents when needed.
Next Up
Chapter 6: Binary Search
Master the art of binary search—not just on arrays, but on the answer itself.
Interview Deep-Dive
Given an array of positive integers and a target sum S, find the length of the shortest subarray with sum >= S. What is your approach, complexity, and why does the sliding window technique work here?
Given an array of positive integers and a target sum S, find the length of the shortest subarray with sum >= S. What is your approach, complexity, and why does the sliding window technique work here?
Strong Answer:
- This is a variable-size sliding window problem. Maintain a left and right pointer, expand right to increase the window sum, and shrink left while the sum is >= S. Track the minimum window length seen.
- Why it works: because all elements are positive, expanding the window (moving right) always increases the sum, and shrinking (moving left) always decreases it. This monotonicity guarantees that each pointer moves at most n times total, giving O(n) time.
- Key insight for “minimum length” windows: shrink while valid. The moment the window sum drops below S, stop shrinking and resume expanding. This is the opposite of “maximum length” windows where you shrink while invalid.
- Edge case: if the total array sum is less than S, no valid subarray exists — return 0 or -1 as specified. Also, a single element might satisfy the condition (element >= S), so minimum length could be 1.
- Complexity: O(n) time, O(1) space. Each pointer visits each element at most once, so total operations are at most 2n.
Compare the two-pointer technique with the hashmap-based approach for the Two Sum problem. When would you choose each?
Compare the two-pointer technique with the hashmap-based approach for the Two Sum problem. When would you choose each?
Strong Answer:
- Two-pointer approach: sort the array, then use converging pointers from both ends. Time: O(n log n) for sort + O(n) for scan = O(n log n). Space: O(1) if sorting in-place (or O(n) for the sorted copy).
- Hashmap approach: single pass, for each element check if (target - element) exists in the hashmap. Time: O(n) average. Space: O(n) for the hashmap.
- Choose two pointers when: you need to find all pairs (not just one), the array is already sorted, you need to solve the problem in O(1) space, or you want to avoid hash collision risks on competitive programming judges.
- Choose hashmap when: you need O(n) time (log factor matters), you must preserve original indices (sorting destroys index information), or the problem has follow-up operations that benefit from the hashmap (e.g., counting pairs, finding the pair closest to target).
- For the classic LeetCode Two Sum that asks for indices: hashmap is the only correct O(n) approach because sorting loses index information. For the Codeforces variant that asks “does such a pair exist”: two pointers after sorting is simpler and avoids hash collision issues.
Find the longest substring with at most K distinct characters. Walk through the sliding window approach and prove its time complexity.
Find the longest substring with at most K distinct characters. Walk through the sliding window approach and prove its time complexity.
Strong Answer:
- Maintain a window [left, right] and a hashmap tracking character frequencies within the window. Expand right, adding each character to the map. When the number of distinct characters exceeds K, shrink from the left: decrement the frequency of s[left], and if it reaches zero, remove it from the map. Track the maximum (right - left + 1) seen.
- Time complexity proof: the right pointer advances from 0 to n-1, making exactly n steps. The left pointer also advances, but crucially it never moves backward. In total, left advances at most n times (it starts at 0 and can reach at most n-1). Each advance of either pointer involves O(1) hashmap work. Total: O(n) + O(n) = O(n).
- The common mistake: computing the number of distinct characters by scanning the hashmap each time — this makes the inner work O(alphabet_size) per step. Instead, maintain a separate counter that increments when a new character is added (frequency goes from 0 to 1) and decrements when a character is removed (frequency goes from 1 to 0). This keeps the distinct count in O(1) per step.
- Window invariant (write this down before coding): “The window [left, right] always contains at most K distinct characters.” When the invariant is violated, shrink until it is restored. Update the answer only when the invariant holds.