Sliding Window Technique : Patterns & Use Cases
What is Sliding Window technique?
Sliding window is a technique used for solving problems involving arrays, lists, or strings by processing a fixed-size portion of the data at a time. It’s often used to efficiently find subarrays, substrings, or windows that meet a specific criteria. It is mostly used when the solution to the problem lies in a contiguous part of the data that is being processed.
Let’s take a classic example to illustrate how sliding window helps in reducing the time complexity while solving problems.
Problem : Suppose we’re given an array and asked to find the maximum sum of any subarray of size k
.
Bruteforce Solution : A straightforward brute-force approach would involve iterating through all possible subarrays of size k
, calculating the sum for each one from scratch. This results in a time complexity of O(n * k), which becomes inefficient as the array grows larger.
Sliding Window Approach : By using the sliding window technique, we can reduce the time complexity from O(n * k) to O(n). The concept is straightforward yet highly effective: At first, we begin by calculating the sum of the first window of size k. As we move the window forward one element at a time, we subtract the element that leaves the window and add the new element that enters. This allows us to update the sum in constant time, without recalculating the entire window each time. This approach minimizes redundant computations and provides a much more efficient and scalable solution for problems involving contiguous subarrays or substrings.
Now with the help of some problems, let us try to understand the common Sliding Window patterns.
🧩 Pattern 1: Fixed-Size Sliding Window
📘 Problem: Maximum Average Subarray I (Leetcode 643)
Link: https://leetcode.com/problems/maximum-average-subarray-i/
📝 Problem Statement
Given an integer array nums
consisting of n
elements and an integer k
, find the maximum average value of any contiguous subarray of length k
.
Return the maximum average value as a double
.
🔹 Constraints:
1 <= k <= n <= 10^5
-10^4 <= nums[i] <= 10^4
🧠 Approach: Sliding Window (Fixed Size)
Since we’re asked to compute something over every subarray of a fixed size k
, this is a classic case for the fixed-size sliding window technique.
✅ Key Idea:
- Start by computing the sum of the first
k
elements (this forms the first window). - Then slide the window by one element at a time:
- Subtract the element that’s going out of the window (on the left).
- Add the new element that’s coming into the window (on the right).
- Keep track of the maximum sum observed.
- Finally, return the maximum sum divided by
k
to get the average.
⏱ Time Complexity:
- O(n) — We traverse the array only once.
🔍 Java Code
public class Solution {
public double findMaxAverage(int[] nums, int k) {
int windowSum = 0;
// Step 1: Sum of the first window
for (int i = 0; i < k; i++) {
windowSum += nums[i];
}
int maxSum = windowSum;
// Step 2: Slide the window through the array
for (int i = k; i < nums.length; i++) {
windowSum += nums[i] - nums[i - k]; // Slide window
maxSum = Math.max(maxSum, windowSum);
}
// Step 3: Return max average
return (double) maxSum / k;
}
}
🧩 Pattern 2: Variable-Size Sliding Window
📘 Problem: Longest Substring Without Repeating Characters (Leetcode 3)
Link: https://leetcode.com/problems/longest-substring-without-repeating-characters/
📝 Problem Statement
Given a string s
, find the length of the longest substring without repeating characters.
🔹 Constraints:
0 <= s.length <= 5 * 10^4
s
consists of English letters, digits, symbols, and spaces.
🧠 Approach: Sliding Window (Variable Size)
This problem requires us to find the longest contiguous substring where no characters repeat — the window can grow and shrink depending on whether the constraint (no duplicates) is satisfied.
Hence, this is a perfect case for a variable-size sliding window.
✅ Key Idea:
- Use two pointers:
start
andend
to denote the current window. - Expand the
end
pointer and add characters to a set/map until a duplicate is found. - If a duplicate is found, shrink the window from the
start
side until the window becomes valid again (no duplicates). - Track the maximum length of a valid window throughout the process.
⏱ Time Complexity:
- O(n) — Each character is visited at most twice (once by
end
, once bystart
). - O(k) space — For the character set/map, where
k
is the number of unique characters.
🔍 Java Code
import java.util.HashSet;
public class Solution {
public int lengthOfLongestSubstring(String s) {
int start = 0, end = 0, maxLen = 0;
HashSet<Character> seen = new HashSet<>();
while (end < s.length()) {
char current = s.charAt(end);
// If duplicate found, shrink from the left
while (seen.contains(current)) {
seen.remove(s.charAt(start));
start++;
}
seen.add(current);
maxLen = Math.max(maxLen, end - start + 1);
end++;
}
return maxLen;
}
}
🧩 Pattern 3: Variable-Size Sliding Window with HashMap/HashSet (Frequency Tracking)
📘 Problem: Minimum Window Substring (Leetcode 76)
Link: https://leetcode.com/problems/minimum-window-substring/
📝 Problem Statement
Given two strings s
and t
, return the minimum window substring of s
such that every character in t
(including duplicates) is included in the window. If there is no such substring, return an empty string ""
.
🧠 Approach: Sliding Window with Frequency Map
This problem requires us to find the smallest substring in s
containing all characters of t
. The window size is variable and the condition depends on character frequencies.
Hence, we use:
- Two pointers defining the sliding window (
start
andend
). - A frequency map to track counts of characters needed.
- A count of how many required characters are currently matched.
✅ Key Idea:
- Build a frequency map of characters in
t
. - Expand the
end
pointer to include characters froms
and update the map. - Once the current window satisfies the requirement (contains all chars of
t
), try shrinking it fromstart
to find a smaller valid window. - Track the minimum length window that satisfies the condition.
⏱ Time Complexity:
- O(n + m) where
n
is the length ofs
andm
is the length oft
. - Each character is visited at most twice by the sliding window pointers.
🔍 Java Code
import java.util.HashMap;
public class Solution {
public String minWindow(String s, String t) {
if (s.length() < t.length()) return "";
// Frequency map for characters in t
HashMap<Character, Integer> freqMap = new HashMap<>();
for (char c : t.toCharArray()) {
freqMap.put(c, freqMap.getOrDefault(c, 0) + 1);
}
int required = freqMap.size(); // Number of unique chars needed
int formed = 0; // How many unique chars currently satisfied
// Window pointers and result tracking
int left = 0, right = 0;
int minLen = Integer.MAX_VALUE;
int minStart = 0;
// Map to count chars in the current window
HashMap<Character, Integer> windowCounts = new HashMap<>();
while (right < s.length()) {
char c = s.charAt(right);
windowCounts.put(c, windowCounts.getOrDefault(c, 0) + 1);
// Check if current char meets the desired frequency
if (freqMap.containsKey(c) && windowCounts.get(c).intValue() == freqMap.get(c).intValue()) {
formed++;
}
// Try to contract the window while it still satisfies the condition
while (left <= right && formed == required) {
c = s.charAt(left);
// Update minimum window if smaller
if (right - left + 1 < minLen) {
minLen = right - left + 1;
minStart = left;
}
// Remove left char from window
windowCounts.put(c, windowCounts.get(c) - 1);
if (freqMap.containsKey(c) && windowCounts.get(c).intValue() < freqMap.get(c).intValue()) {
formed--;
}
left++;
}
right++;
}
return minLen == Integer.MAX_VALUE ? "" : s.substring(minStart, minStart + minLen);
}
}
🧩 Pattern 3: Variable-Size Sliding Window with HashMap/HashSet (Frequency Tracking)
📘 Problem: Replace the Substring for Balanced String (Leetcode 1234)
Link: https://leetcode.com/problems/replace-the-substring-for-balanced-string/
🔍 Problem Summary
Given a string s consisting only of characters ‘Q’, ‘W’, ‘E’, and ‘R’.
The string is considered balanced if each of these four characters occurs exactly n/4 times, where n is the length of the string.
Our task is to find the minimum length of a substring that you can replace (with any combination of characters) such that the resulting string is balanced.
🎯 Goal
Find the minimum window (substring) length that, if replaced with any characters, would make the entire string balanced.
🧠 Key Observations
Target frequency per character is s.length() / 4.
If a character appears more than that, it is in excess.
We don’t care what you replace the substring with — just that replacing it reduces the overrepresented characters.
✅ Step 1: Count the characters Use a map or array to count how many ‘Q’, ‘W’, ‘E’, and ‘R’ appear in s. Determine which characters are in excess (greater than n/4).
✅ Step 2: Use a Sliding Window Try to find the smallest window such that removing it from the string allows the remaining part to become balanced.= In the window, we need to track character counts. Using two pointers (left and right) to shrink and expand the window.
✅ Step 3: Validation Condition While sliding the window, we need to check if the characters outside the window satisfy the required frequency (i.e., none of the characters are overrepresented anymore).
⏱ Time Complexity: O(n)
🔍 Java Code
class Solution {
public int balancedString(String s) {
int n = s.length();
int requiredFreq = n / 4;
int[] count = new int[128];
for (char c : s.toCharArray()) {
count[c]++;
}
if (count['Q'] == requiredFreq && count['W'] == requiredFreq &&
count['E'] == requiredFreq && count['R'] == requiredFreq) {
return 0;
}
int left = 0, right = 0, minLen = n;
while (right < n) {
count[s.charAt(right)]--;
while (left <= right &&
count['Q'] <= requiredFreq &&
count['W'] <= requiredFreq &&
count['E'] <= requiredFreq &&
count['R'] <= requiredFreq) {
minLen = Math.min(minLen, right - left + 1);
count[s.charAt(left)]++;
left++;
}
right++;
}
return minLen;
}
}