Skip to main content

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.


🧠 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​

TypeWindow SizeUse When
Fixed WindowConstant (K)Problem gives a fixed size K
Variable WindowGrows & shrinksFind 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​

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

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​

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

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 TypeTimeSpace
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​

  1. Forgetting to shrink the window β€” Always move left forward when your condition is violated.
  2. Using nested loops β€” If you see O(nΒ²) on a subarray problem, think Sliding Window.
  3. Wrong window size formula β€” Current window size is always right - left + 1.
  4. Not handling edge cases β€” Empty array, K larger than array length.
  5. Reinitializing variables inside the loop β€” max_sum, left should be declared outside.

πŸ‹οΈ Practice Problems​

#ProblemTypeDifficulty
1Maximum Sum Subarray of Size KFixed🟒 Easy
2Average of Subarrays of Size KFixed🟒 Easy
3Longest Substring Without Repeating CharactersVariable🟑 Medium
4Minimum Size Subarray SumVariable🟑 Medium
5Fruits Into BasketsVariable🟑 Medium
6Longest Repeating Character ReplacementVariable🟑 Medium
7Permutation in StringFixed🟑 Medium
8Minimum Window SubstringVariableπŸ”΄ Hard
9Sliding Window MaximumFixed + DequeπŸ”΄ Hard

πŸ”— References​