Sliding Window solves problems on contiguous subarrays by maintaining a window instead of recomputing it.
Its core idea:
Add the incoming element, remove the outgoing one — each element enters and leaves the window once.
Focus on recognizing:
Exactly K → Fixed window · Longest/shortest + condition → Variable window
Quick Recognition Cheat Sheet
| If you see… | Think… | Main Idea |
|---|---|---|
| Exactly K elements | Fixed Window | Add incoming, remove outgoing |
| Maximum/minimum of size K | Fixed Window | Keep window size K |
| Longest subarray satisfying condition | Variable Window | Expand, then shrink if needed |
| Shortest subarray satisfying condition | Variable Window | Expand, shrink aggressively |
1. Fixed-Size Window
The window always contains exactly K elements.
Core Idea
Add incoming element
Remove outgoing element
Update result
⚠️ Animation & Content Notice
The animation work is not fully finished — some animations may have slight errors.
If there is a major error in the content or if the animation or content is difficult to understand, please contact us at rayyancodingschool@gmail.com.
Longest Substring Without Repeating Characters
Grow a window with the right pointer; whenever a duplicate enters, jump the left pointer just past the previous copy. The window always holds distinct characters, and its max size is the answer.
String 'abcabcbb'. ▼L/▼R carets and the highlighted range ARE the window. As R advances, 'a' appears again at right=3 so L jumps past the old 'a' (window 'bca'). Repeat: max window length = 3 ('abc'). The window never holds a repeat — that's the whole invariant.
1
left = 0
2
for right from 0 to n-1:
3
if s[right] is already in window:
4
left = move past the old copy
5
add s[right] to window
6
best = longest window so far
7
return best
public int maxSumFixed(int[] nums, int k) {
int sum = 0;
for (int i = 0; i < k; i++) {
sum += nums[i];
}
int max = sum;
for (int i = k; i < nums.length; i++) {
sum += nums[i] - nums[i - k];
max = Math.max(max, sum);
}
return max;
}def max_sum_fixed(nums, k):
window = sum(nums[:k])
best = window
for i in range(k, len(nums)):
window += nums[i] - nums[i - k]
best = max(best, window)
return bestint maxSumFixed(vector<int>& nums, int k) {
int sum = 0;
for (int i = 0; i < k; i++) sum += nums[i];
int best = sum;
for (int i = k; i < (int)nums.size(); i++) {
sum += nums[i] - nums[i - k];
best = max(best, sum);
}
return best;
}function maxSumFixed(nums, k) {
let sum = 0;
for (let i = 0; i < k; i++) sum += nums[i];
let max = sum;
for (let i = k; i < nums.length; i++) {
sum += nums[i] - nums[i - k];
max = Math.max(max, sum);
}
return max;
}Fixed K = Add incoming − Remove outgoing.
2. Variable-Size Window
The window size changes depending on a condition.
Core Idea
Expand right
↓
Check condition
↓
If invalid → shrink left
↓
Update answer
⚠️ Animation & Content Notice
The animation work is not fully finished — some animations may have slight errors.
If there is a major error in the content or if the animation or content is difficult to understand, please contact us at rayyancodingschool@gmail.com.
Minimum Window Substring (Contains All of T)
Given S = "ADOBECODEBANC" and T = "ABC", find the shortest substring of S that contains at least one A, one B, and one C. The expected answer is "BANC", which has length 4.
Use a sliding window [left, right] and frequency counts for the target characters A, B, and C. For S = "ADOBECODEBANC" and T = "ABC", expand right until the window contains all three required characters. At right = 5, the window "ADOBEC" becomes valid with matched = 3. Save it, then shrink from the left one character at a time while it remains valid. Removing A makes the window invalid, so stop. Continue expanding. At right = 12, the window "ODEBANC" is valid again. Shrink it: removing O gives "DEBANC", removing D gives "EBANC", removing E gives "BANC", which is still valid and has length 4. Removing B would make the window invalid because no B remains, so stop. Therefore the minimum window is "BANC".
1
left = 0, matched = 0
2
for right from 0 to n-1:
3
add s[right] to window
4
if count matches target: matched = matched + 1
5
while all chars of t are matched:
6
if window is smaller than best: save it
7
remove s[left] from window
8
if removing breaks a match: matched = matched - 1
9
left = left + 1
10
return saved window
public int longestSubarray(int[] nums, int k) {
int left = 0;
int sum = 0;
int result = 0;
for (int right = 0; right < nums.length; right++) {
sum += nums[right];
while (sum > k) {
sum -= nums[left];
left++;
}
result = Math.max(result, right - left + 1);
}
return result;
}def longest_subarray(nums, k):
left = 0
window = 0
best = 0
for right in range(len(nums)):
window += nums[right]
while window > k:
window -= nums[left]
left += 1
best = max(best, right - left + 1)
return bestint longestSubarray(vector<int>& nums, int k) {
int left = 0, sum = 0, best = 0;
for (int right = 0; right < (int)nums.size(); right++) {
sum += nums[right];
while (sum > k) {
sum -= nums[left];
left++;
}
best = max(best, right - left + 1);
}
return best;
}function longestSubarray(nums, k) {
let left = 0,
sum = 0,
result = 0;
for (let right = 0; right < nums.length; right++) {
sum += nums[right];
while (sum > k) {
sum -= nums[left];
left++;
}
result = Math.max(result, right - left + 1);
}
return result;
}Watch the variable window grow over [1,2,3,4,5] until sum ≤ 8 breaks, shrink back to valid, and finish with best length 3. Press ▶ to animate.
3. Longest vs Shortest
The most important distinction:
Longest
Shrink only until the window becomes valid — update after shrinking.
while (condition is invalid) { shrink(); }
result = max(result, windowSize);
Shortest
Once valid, keep shrinking while it stays valid — update during shrinking.
while (condition is valid) {
result = min(result, windowSize);
shrink();
}
Longest → update after shrinking. Shortest → update during shrinking.
Common Mistakes
Confusing fixed and variable windows.
Exactly K → Fixed. Longest/shortest satisfying a condition → Variable.
Using if instead of while.
One removal may not restore validity — shrink in a loop.
Off-by-one on window length.
Length is always right - left + 1.
Complexity
| Pattern | Time |
|---|---|
| Fixed window | O(n) |
| Variable window | O(n) — each index enters and leaves once |
Premium Content
Unlock Sliding Window and all premium lessons with a subscription.
From ₹199.99/year — See plans