Sliding Window Algorithm
Sliding Window Algorithm
The Sliding Window technique is one of the most powerful patterns in DSA. It converts an O(nยฒ) brute-force approach into an elegant O(n) solution for problems involving contiguous subarrays or substrings.
Video Explanationโ

๐ง Core Ideaโ
Instead of recalculating from scratch for every subarray, we maintain a window and slide it across the array โ adding one element on the right and removing one on the left.
Array: [ 2, 1, 5, 1, 3, 2 ] K = 3
Window 1: [2, 1, 5] โ sum = 8
โ slide
Window 2: [1, 5, 1] โ sum = 7 (remove 2, add 1)
โ slide
Window 3: [5, 1, 3] โ sum = 9 (remove 1, add 3) โ MAX
โ slide
Window 4: [1, 3, 2] โ sum = 6 (remove 5, add 2)
๐๏ธ Types of Sliding Windowโ
| Type | Window Size | Use When |
|---|---|---|
| Fixed Window | Constant (K) | Problem gives a fixed size K |
| Variable Window | Grows & shrinks | Find longest/shortest satisfying a condition |
๐ Type 1: Fixed Size Sliding Windowโ
When to Useโ
- "Find max/min sum of subarray of size K"
- "Find average of every subarray of size K"
- The window size is given directly in the problem
Visual Diagramโ
Problem: Max sum subarray of size K=3
Array = [2, 1, 5, 1, 3, 2]
STEP 1: Build first window
โโโโโโโโโโโโโโโโโโโ
โ 2 โ 1 โ 5 โ 1 3 2
โโโโโโโโโโโโโโโโโโโ
sum = 8 max = 8
STEP 2: Slide โ remove left, add right
โโโโโโโโโโโโโโโโโโโ
2 โ 1 โ 5 โ 1 โ 3 2
โโโโโโโโโโโโโโโโโโโ
sum = 8 - 2 + 1 = 7 max = 8
STEP 3: Slide again
โโโโโโโโโโโโโโโโโโโ
2 1 โ 5 โ 1 โ 3 โ 2
โโโโโโโโโโโโโโโโโโโ
sum = 7 - 1 + 3 = 9 max = 9 โ
STEP 4: Slide again
โโโโโโโโโโโโโโโโโโโ
2 1 5 โ 1 โ 3 โ 2 โ
โโโโโโโโโโโโโโโโโโโ
sum = 9 - 5 + 2 = 6 max = 9
Answer: 9
Code Templateโ
- Python
- Java
- C++
def max_sum_subarray(arr, k):
n = len(arr)
if n < k:
return -1
# Step 1: Build first window
window_sum = sum(arr[:k])
max_sum = window_sum
# Step 2: Slide the window
for i in range(k, n):
window_sum += arr[i] # Add incoming element (right)
window_sum -= arr[i - k] # Remove outgoing element (left)
max_sum = max(max_sum, window_sum)
return max_sum
# Example
arr = [2, 1, 5, 1, 3, 2]
print(max_sum_subarray(arr, 3)) # Output: 9
public class SlidingWindow {
public static long maxSumSubarray(int[] arr, int k) {
int n = arr.length;
if (n < k) return -1;
// Step 1: Build first window
long windowSum = 0;
for (int i = 0; i < k; i++) {
windowSum += arr[i];
}
long maxSum = windowSum;
// Step 2: Slide the window
for (int i = k; i < n; i++) {
windowSum += arr[i]; // Add incoming element (right)
windowSum -= arr[i - k]; // Remove outgoing element (left)
maxSum = Math.max(maxSum, windowSum);
}
return maxSum;
}
public static void main(String[] args) {
int[] arr = {2, 1, 5, 1, 3, 2};
System.out.println(maxSumSubarray(arr, 3)); // Output: 9
}
}
#include <bits/stdc++.h>
using namespace std;
long long maxSumSubarray(vector<int>& arr, int k) {
int n = arr.size();
if (n < k) return -1;
// Step 1: Build first window
long long windowSum = 0;
for (int i = 0; i < k; i++) {
windowSum += arr[i];
}
long long maxSum = windowSum;
// Step 2: Slide the window
for (int i = k; i < n; i++) {
windowSum += arr[i]; // Add incoming element (right)
windowSum -= arr[i - k]; // Remove outgoing element (left)
maxSum = max(maxSum, windowSum);
}
return maxSum;
}
int main() {
vector<int> arr = {2, 1, 5, 1, 3, 2};
cout << maxSumSubarray(arr, 3) << endl; // Output: 9
return 0;
}
Time Complexity: O(n) ย |ย Space Complexity: O(1)
๐ Type 2: Variable Size Sliding Windowโ
When to Useโ
- "Find the longest substring/subarray satisfying a condition"
- "Find the smallest subarray with sum โฅ target"
- Window size is not fixed โ it expands and shrinks based on a condition
How it Worksโ
Two pointers: LEFT and RIGHT
- RIGHT expands the window (moves forward always)
- LEFT shrinks the window (moves forward when condition is violated)
LEFT RIGHT
โ โ
[ a b c d e f g ]
โโโโwindowโโโ
Classic Problem: Longest Substring Without Repeating Charactersโ
Input: s = "a b c a b c b b"
0 1 2 3 4 5 6 7
right=0: window="a" no repeat โ length=1
right=1: window="ab" no repeat โ length=2
right=2: window="abc" no repeat โ length=3
right=3: 'a' REPEATS!
โ shrink: remove s[left]='a', left=1
โ window="bca" no repeat โ length=3
right=4: 'b' REPEATS!
โ shrink: remove s[left]='b', left=2
โ window="cab" no repeat โ length=3
right=5: 'c' REPEATS!
โ shrink: remove s[left]='c', left=3
โ window="abc" no repeat โ length=3
right=6: 'b' REPEATS!
โ shrink until valid: left=5
โ window="cb" length=2
right=7: 'b' REPEATS!
โ shrink: left=7
โ window="b" length=1
โ
Answer: 3 ("abc")
Code Templateโ
- Python
- Java
- C++
def longest_substring_no_repeat(s):
char_map = {} # stores char โ last seen index
left = 0
max_length = 0
for right in range(len(s)):
# If char is already in window, shrink from left
if s[right] in char_map and char_map[s[right]] >= left:
left = char_map[s[right]] + 1
# Update last seen position
char_map[s[right]] = right
# Update max length
max_length = max(max_length, right - left + 1)
return max_length
# Example
print(longest_substring_no_repeat("abcabcbb")) # Output: 3
print(longest_substring_no_repeat("pwwkew")) # Output: 3
import java.util.HashMap;
public class SlidingWindow {
public static int lengthOfLongestSubstring(String s) {
HashMap<Character, Integer> charMap = new HashMap<>();
int left = 0;
int maxLength = 0;
for (int right = 0; right < s.length(); right++) {
char c = s.charAt(right);
// If char is already in window, shrink from left
Integer lastSeen = charMap.get(c);
if (lastSeen != null && lastSeen >= left) {
left = lastSeen + 1;
}
// Update last seen position
charMap.put(c, right);
// Update max length
maxLength = Math.max(maxLength, right - left + 1);
}
return maxLength;
}
public static void main(String[] args) {
System.out.println(lengthOfLongestSubstring("abcabcbb")); // Output: 3
}
}
#include <bits/stdc++.h>
using namespace std;
int lengthOfLongestSubstring(string s) {
unordered_map<char, int> charMap;
int left = 0;
int maxLength = 0;
int n = s.size();
for (int right = 0; right < n; right++) {
auto it = charMap.find(s[right]);
if (it != charMap.end() && it->second >= left) {
left = it->second + 1;
}
// Update last seen position
charMap[s[right]] = right;
// Update max length
maxLength = max(maxLength, right - left + 1);
}
return maxLength;
}
int main() {
cout << lengthOfLongestSubstring("abcabcbb") << endl; // Output: 3
return 0;
}
Time Complexity: O(n) ย |ย Space Complexity: O(k) where k = unique characters
โก Brute Force vs Sliding Windowโ
Problem: Max sum subarray of size K=3
Array = [2, 1, 5, 1, 3, 2]
โ BRUTE FORCE โ O(nยฒ)
Window [0..2]: 2+1+5 = 8 (3 additions)
Window [1..3]: 1+5+1 = 7 (3 additions)
Window [2..4]: 5+1+3 = 9 (3 additions)
Window [3..5]: 1+3+2 = 6 (3 additions)
Total: 12 operations
โ
SLIDING WINDOW โ O(n)
Window [0..2]: 2+1+5 = 8 (3 additions for first window)
Window [1..3]: 8 - 2 + 1 = 7 (1 subtraction + 1 addition)
Window [2..4]: 7 - 1 + 3 = 9 (1 subtraction + 1 addition)
Window [3..5]: 9 - 5 + 2 = 6 (1 subtraction + 1 addition)
Total: 9 operations โ
Faster!
๐ Complexity Summaryโ
| Problem Type | Time | Space |
|---|---|---|
| Fixed window (sum, avg) | O(n) | O(1) |
| Variable window (longest substring) | O(n) | O(k) |
| Variable window (smallest subarray) | O(n) | O(1) |
โ Common Mistakesโ
- Forgetting to shrink the window โ Always move
leftforward when your condition is violated. - Using nested loops โ If you see O(nยฒ) on a subarray problem, think Sliding Window.
- Wrong window size formula โ Current window size is always
right - left + 1. - Not handling edge cases โ Empty array, K larger than array length.
- Reinitializing variables inside the loop โ
max_sum,leftshould be declared outside.
๐๏ธ Practice Problemsโ
| # | Problem | Type | Difficulty |
|---|---|---|---|
| 1 | Maximum Sum Subarray of Size K | Fixed | ๐ข Easy |
| 2 | Average of Subarrays of Size K | Fixed | ๐ข Easy |
| 3 | Longest Substring Without Repeating Characters | Variable | ๐ก Medium |
| 4 | Minimum Size Subarray Sum | Variable | ๐ก Medium |
| 5 | Fruits Into Baskets | Variable | ๐ก Medium |
| 6 | Longest Repeating Character Replacement | Variable | ๐ก Medium |
| 7 | Permutation in String | Fixed | ๐ก Medium |
| 8 | Minimum Window Substring | Variable | ๐ด Hard |
| 9 | Sliding Window Maximum | Fixed + Deque | ๐ด Hard |
๐ Related Topicsโ
- Monotonic Stack & Queue: Efficient technique for next greater element and sliding window maximum ().
- Trie: Tree structure specialized for prefix lookups and string processing ().
- Dijkstra's Algorithm: Shortest path algorithm for non-negative weighted graphs ().
๐ Referencesโ
Test Your Understanding
Answer these 3 questions to check what you have learned.
What is the main topic of this documentation page?
What should be identified before implementing sliding window?
How is understanding of sliding window best checked?
Done with this topic? Mark it as complete to track your progress.