Sliding Window: Code Templates in 6 Languages
If you have not read the concept guide yet, start there for the intuition and the complexity analysis. This page gives you the code you can memorize and adapt during an interview. Every template here runs in
The core of every sliding window is the same. A right pointer grows the window, a left pointer shrinks it, and a running state makes the window answerable in constant time. What changes between problems is what the state holds and when the result is recorded.
Main Template: Variable Size Window (Minimum Length)
This is the classic sliding window. It expands the window until the condition holds, then shrinks from the left to find the shortest window that still satisfies the condition. This template directly solves Minimum Size Subarray Sum .
function minSubArrayLen(target, nums) {
let left = 0;
let windowSum = 0;
let result = Infinity;
for (let right = 0; right < nums.length; right++) {
windowSum += nums[right];
// While the window is valid, every window is a candidate,
// so the shortest one is recorded before the left edge moves
while (windowSum >= target) {
result = Math.min(result, right - left + 1);
windowSum -= nums[left];
left++;
}
}
// No window ever reached the target value
return result === Infinity ? 0 : result;
}Code Breakdown
Key Variables
left: the left boundary of the window. It moves only when the window is valid, and it never moves backward.right: the right boundary. Moves forward on every iteration of the loop, adding the current element to the window state.windowSum(or whatever the state is named): holds the running data for the current window. In the shrink case it holds a number, in frequency windows it holds a character table.result: the best answer found so far. For min-length problems it starts at infinity, and the sentinel survives if no valid window exists.
The Flow
stateDiagram-v2
[*] --> Expand: right++, add nums[right]
Expand --> Check: windowSum >= target?
Check --> Record: yes
Record --> Shrink: subtract nums[left], left++
Shrink --> Check: still valid
Check --> Expand: no
Expand --> Done: right = n
Done --> [*]
Why the record happens before the shrink
The trick in this main template is the ordering. The record happens before the shrink. When the window sum passes the target, every shorter window you can reach by dropping elements from the left is also a valid candidate. The record has to happen before the element leaves, because the moment after you subtract it the window may no longer satisfy the condition, and the candidate would be lost.
The loop is linear because of the same ordering: the while may run several times in one iteration, but each pass through it removes exactly one element, and the left pointer never resets. Across the whole run, left visits each index at most once.
Variations
1. Fixed Size Window
The window always has exactly k elements. Record at every step once the window is full, and from then on each right step evicts one element with a simple subtraction.
Use this for Maximum Average Subarray I .
function maxSumWindow(nums, k) {
let windowSum = 0;
let maxSum = 0;
for (let i = 0; i < nums.length; i++) {
windowSum += nums[i];
// The window fills at index k - 1. From then on, each step
// records a full window and evicts the element that fell out
if (i >= k - 1) {
maxSum = Math.max(maxSum, windowSum);
windowSum -= nums[i - k + 1];
}
}
return maxSum;
}2. Frequency Map Window
When the condition is about character counts instead of sums, the state becomes a map of characters in the window. The shrink condition is a count check instead of a sum comparison.
Use this for Longest Substring Without Repeating Characters on the problems page .
function longestUnique(s) {
const counts = new Map();
let left = 0;
let maxLen = 0;
for (let right = 0; right < s.length; right++) {
const char = s[right];
counts.set(char, (counts.get(char) || 0) + 1);
// A duplicate character makes the window invalid. Shrink
// until only one copy of char remains inside
while (counts.get(char) > 1) {
const leftChar = s[left];
counts.set(leftChar, counts.get(leftChar) - 1);
left++;
}
maxLen = Math.max(maxLen, right - left + 1);
}
return maxLen;
}Note that the fixed-size and variable-size templates share one rule. The result is recorded at the moment the window satisfies its condition, and the state only changes at the edges. Everything else in a sliding window problem is the problem-specific condition.
Now head to the practice problems section to apply these templates to real interview questions.