Sliding Window Pattern
š Concept
The sliding window pattern maintains a "window" (subarray/substring) that expands and contracts as you iterate. It's one of the most powerful patterns for substring and subarray problems.
Two types:
1. Fixed-size window:
- Window size is given (e.g., "maximum sum of subarray of size k")
- Slide the window by adding the right element and removing the left element
- O(n) ā each element enters and leaves the window once
2. Variable-size window:
- Expand right to include more elements
- Shrink left when a condition is violated
- Track the optimal window (min length, max length, etc.)
- O(n) ā right pointer moves n times, left pointer moves at most n times total
Variable window template:
let left = 0;
for (let right = 0; right < n; right++) {
// Add arr[right] to window
while (window violates condition) {
// Remove arr[left] from window
left++;
}
// Update answer with current valid window
}
When to use sliding window:
- "Find longest/shortest subarray/substring with property X"
- "Maximum/minimum sum of subarray of size K"
- "Contains all characters of target string"
- Contiguous sequence problems
š Real-world analogy: Sliding window is like reading with a magnifying glass that you slide across text. You control the size of the lens ā zoom in (shrink) or zoom out (expand) ā to find the section you're looking for.
š» Code Example
1// FIXED WINDOW ā Max sum subarray of size k2function maxSumSubarray(arr: number[], k: number): number {3 let windowSum = 0, maxSum = -Infinity;4 for (let i = 0; i < arr.length; i++) {5 windowSum += arr[i]; // Add right element6 if (i >= k) windowSum -= arr[i - k]; // Remove left element7 if (i >= k - 1) maxSum = Math.max(maxSum, windowSum);8 }9 return maxSum;10}1112// VARIABLE WINDOW ā Longest substring without repeating chars13function longestUnique(s: string): number {14 const seen = new Set<string>();15 let left = 0, maxLen = 0;16 for (let right = 0; right < s.length; right++) {17 while (seen.has(s[right])) {18 seen.delete(s[left]);19 left++;20 }21 seen.add(s[right]);22 maxLen = Math.max(maxLen, right - left + 1);23 }24 return maxLen;25}2627// VARIABLE WINDOW ā Minimum window substring28function minWindow(s: string, t: string): string {29 const need = new Map<string, number>();30 for (const c of t) need.set(c, (need.get(c) || 0) + 1);3132 let have = 0, required = need.size;33 let left = 0, minLen = Infinity, minStart = 0;34 const window = new Map<string, number>();3536 for (let right = 0; right < s.length; right++) {37 const c = s[right];38 window.set(c, (window.get(c) || 0) + 1);39 if (need.has(c) && window.get(c) === need.get(c)) have++;4041 while (have === required) {42 if (right - left + 1 < minLen) {43 minLen = right - left + 1;44 minStart = left;45 }46 const lc = s[left];47 window.set(lc, window.get(lc)! - 1);48 if (need.has(lc) && window.get(lc)! < need.get(lc)!) have--;49 left++;50 }51 }52 return minLen === Infinity ? "" : s.substring(minStart, minStart + minLen);53}5455// FIXED WINDOW ā Find all anagrams of pattern in string56function findAnagrams(s: string, p: string): number[] {57 const result: number[] = [];58 const need = new Array(26).fill(0);59 const have = new Array(26).fill(0);60 const a = 'a'.charCodeAt(0);6162 for (const c of p) need[c.charCodeAt(0) - a]++;6364 for (let i = 0; i < s.length; i++) {65 have[s.charCodeAt(i) - a]++;66 if (i >= p.length) have[s.charCodeAt(i - p.length) - a]--;67 if (have.toString() === need.toString()) result.push(i - p.length + 1);68 }69 return result;70}
šļø Practice Exercise
Practice Problems (Easy ā Hard):
- Maximum sum subarray of size k (fixed window)
- Longest substring without repeating characters
- Find all anagrams of a pattern in a string
- Longest substring with at most k distinct characters
- Minimum size subarray with sum ā„ target
- Maximum number of vowels in a substring of size k
- Longest repeating character replacement (with at most k changes)
- Minimum window substring (contains all chars of target)
- Sliding window maximum (use deque for O(n))
- Subarrays with k different integers
ā ļø Common Mistakes
Not recognizing when sliding window applies ā look for 'contiguous subarray/substring' keywords
Forgetting to shrink the window ā the left pointer must move to maintain the window condition
Using O(n) comparison in the loop (e.g., comparing full hash maps) ā use counters instead for O(1)
Confusing fixed and variable window ā fixed: always size k, variable: shrink/expand to optimize
Not updating the answer at the right time ā update AFTER ensures condition, not before
š¼ Interview Questions
š¤ Mock Interview
Practice a live interview for Sliding Window Pattern