LeetCode Pattern/Sliding Window/Sliding Window Template Explained (Python / Java / JavaScript)

Sliding Window Template Explained (Python / Java / JavaScript)

LeetCopilot Team
Nov 15, 2025
12 min read
Sliding WindowLeetCodeInterview PrepCode TemplatesPythonJavaJavaScript
Master the universal sliding window template across Python, Java, and JavaScript. Learn how to avoid reinventing the wheel and ship bug-free solutions faster in coding interviews.

You're in the middle of a coding interview. The problem screams "Sliding Window"—you know it. But as you start typing, you hesitate. Should you use a while or for loop? When do you expand? When do you shrink? Five minutes later, you're debugging off-by-one errors instead of explaining your approach.

This is exactly why you need a sliding window template. Not just understanding the concept, but having a battle-tested, muscle-memory blueprint that works across Python, Java, and JavaScript.

In this guide, you'll learn:

  • Why templates matter more than ad-hoc solutions
  • The difference between fixed-size and variable-size windows
  • Multi-language templates you can memorize and adapt
  • Common pitfalls and how templates automatically avoid them
  • How to apply the template to real LeetCode problems

By the end, you'll have a single framework that eliminates guesswork and lets you focus on what matters: solving the problem.

TL;DR — Sliding Window Template Essentials

  • Fixed-size window: Use when window size is explicitly given (e.g., "size k")
  • Variable-size window: Use for "longest/shortest" with conditions (e.g., "at most K distinct")
  • Template structure: Expand in for loop, shrink in while loop, update result
  • Common mistake: Calculating window size as right - left instead of right - left + 1
  • Language support: Same pattern works in Python, Java, JavaScript
  • When to avoid: Problems with negative numbers requiring exact sums (use prefix sums instead)

Why a Template Matters

The Risk of Reinventing Loops

Every time you write a sliding window solution from scratch, you're making micro-decisions:

  • "Should I increment right before or after adding to the window state?"
  • "Do I check the condition before or after shrinking left?"
  • "What if the array has one element?"

These aren't conceptual questions—they're implementation landmines. And in an interview, you don't have time to debug them.

I've seen candidates who clearly understood sliding window conceptually but failed because they couldn't translate it into clean code under pressure. They knew what to do, but not how to structure the loop invariants.

How the Template Speeds Up Interview Coding

A memorized template gives you:

  1. Consistency: Same structure every time means fewer bugs
  2. Speed: No mental overhead deciding loop architecture
  3. Clarity: Interviewers recognize the pattern instantly
  4. Confidence: You can explain rather than defend your approach

Think of it like having a code snippet library in your brain. When you see "longest substring with at most K distinct characters," you don't debate syntax—you paste the mental template and fill in the window logic.

Fixed-Size vs Variable-Size Window

Before diving into templates, you need to understand the two fundamental sliding window types. Misidentifying which one you need is the #1 reason candidates pick the wrong template.

Explanation of Each Type

Fixed-Size Window: The window always contains exactly k elements.

Example: "Find maximum sum of any subarray of size 3"

Structure:

# Expand until window reaches size k
# Then slide: add one, remove one
for right in range(len(arr)):
    # Add arr[right]
    if right >= k - 1:
        # Process window
        # Remove arr[right - k + 1]
python

Variable-Size Window: The window grows and shrinks based on a condition.

Example: "Find longest substring where all characters appear at most twice"

Structure:

left = 0
for right in range(len(arr)):
    # Add arr[right] to window
    while window_invalid():
        # Remove arr[left]
        left += 1
    # Update result with current window
python

When to Use Which

Problem TypeFixed or VariableKey Signal
"Subarray of size k"FixedExplicit size constraint
"At most k distinct..."VariableCondition-based constraint
"Maximum/minimum in every window of size k"FixedSliding over all k-windows
"Longest/shortest substring where..."VariableOptimize window size

Interview Tip: If the problem says "size k" or "window of length k," it's fixed. If it says "at most," "at least," "longest," or "shortest," it's variable.

Multi-Language Template Walkthrough

Here are the production-ready templates you should memorize. Each is annotated with the critical decision points.

Python Version: Annotated Code

Variable-Size Template (Most Common)

def sliding_window(arr, condition):
    """
    Universal variable-size sliding window template.
    Works for: longest substring, at-most-k problems, etc.
    """
    left = 0
    window_state = {}  # Could be dict, set, int counter, etc.
    result = 0  # Or float('inf') for minimum problems
    
    for right in range(len(arr)):
        # 1. Expand: Add arr[right] to window state
        # (e.g., window_state[arr[right]] = window_state.get(arr[right], 0) + 1)
        
        # 2. Shrink: While window is invalid, remove from left
        while window_invalid(window_state, condition):
            # Remove arr[left] from window state
            left += 1
        
        # 3. Update result: Current window [left, right] is valid
        result = max(result, right - left + 1)
    
    return result
python

Fixed-Size Template

def fixed_window(arr, k):
    """
    Fixed-size sliding window template.
    Works for: sum of subarray size k, etc.
    """
    window_sum = 0
    result = float('-inf')
    
    for right in range(len(arr)):
        # Expand window
        window_sum += arr[right]
        
        # Once we hit size k, start sliding
        if right >= k - 1:
            result = max(result, window_sum)
            # Shrink from left (maintain size k)
            window_sum -= arr[right - k + 1]
    
    return result
python

Java Version: Annotated Code

Variable-Size Template

public int slidingWindow(int[] arr) {
    int left = 0;
    Map<Integer, Integer> windowState = new HashMap<>();
    int result = 0;
    
    for (int right = 0; right < arr.length; right++) {
        // 1. Expand: Add arr[right]
        windowState.put(arr[right], 
            windowState.getOrDefault(arr[right], 0) + 1);
        
        // 2. Shrink: While invalid
        while (isWindowInvalid(windowState)) {
            // Remove arr[left]
            windowState.put(arr[left], 
                windowState.get(arr[left]) - 1);
            if (windowState.get(arr[left]) == 0) {
                windowState.remove(arr[left]);
            }
            left++;
        }
        
        // 3. Update result
        result = Math.max(result, right - left + 1);
    }
    
    return result;
}
java

Fixed-Size Template

public int fixedWindow(int[] arr, int k) {
    int windowSum = 0;
    int result = Integer.MIN_VALUE;
    
    for (int right = 0; right < arr.length; right++) {
        windowSum += arr[right];
        
        if (right >= k - 1) {
            result = Math.max(result, windowSum);
            windowSum -= arr[right - k + 1];
        }
    }
    
    return result;
}
java

JavaScript Version: Annotated Code

Variable-Size Template

function slidingWindow(arr) {
    let left = 0;
    const windowState = new Map();
    let result = 0;
    
    for (let right = 0; right < arr.length; right++) {
        // 1. Expand
        const rightVal = arr[right];
        windowState.set(rightVal, 
            (windowState.get(rightVal) || 0) + 1);
        
        // 2. Shrink
        while (isWindowInvalid(windowState)) {
            const leftVal = arr[left];
            windowState.set(leftVal, 
                windowState.get(leftVal) - 1);
            if (windowState.get(leftVal) === 0) {
                windowState.delete(leftVal);
            }
            left++;
        }
        
        // 3. Update
        result = Math.max(result, right - left + 1);
    }
    
    return result;
}
javascript

Fixed-Size Template

function fixedWindow(arr, k) {
    let windowSum = 0;
    let result = -Infinity;
    
    for (let right = 0; right < arr.length; right++) {
        windowSum += arr[right];
        
        if (right >= k - 1) {
            result = Math.max(result, windowSum);
            windowSum -= arr[right - k + 1];
        }
    }
    
    return result;
}
javascript

Common Pitfalls & How the Template Avoids Them

Off-by-One Errors

The Trap: Calculating window size as right - left instead of right - left + 1.

Why It Happens: Confusing array indices with array lengths.

How the Template Fixes It: The line result = max(result, right - left + 1) is literally in the template. You don't have to remember—it's always there.

Forgetting to Shrink/Expand Properly

The Trap: Expanding the window without adding to state, or shrinking without removing.

Example:

# WRONG
for right in range(len(arr)):
    # Forgot to update window state here!
    while window_size > k:
        left += 1  # Forgot to remove arr[left] from state!
python

How the Template Fixes It: The template has explicit comments:

# 1. Expand: Add arr[right] to window state
# ...
# 2. Shrink: Remove arr[left] from window state
python

You can't skip these steps because they're structurally enforced.

Mismatched Invariant

The Trap: Checking the window condition at the wrong time.

Example: Checking validity before adding arr[right] means your window never includes the current element.

How the Template Fixes It: The order is always:

  1. Expand (add right)
  2. Shrink (while invalid)
  3. Process valid window

This invariant—"after shrinking, the window is always valid"—is baked into the template structure.

Applying the Template in a Real LeetCode Problem

Let's take Longest Substring Without Repeating Characters (LeetCode #3).

Problem: Given a string s, find the length of the longest substring without repeating characters.

How the Template Maps

  1. Window state: A Set or Map tracking characters in the current window
  2. Invalid condition: When a character appears twice
  3. Result: Maximum window size

Python Solution

def lengthOfLongestSubstring(s: str) -> int:
    left = 0
    char_set = set()  # Window state: track unique chars
    max_length = 0
    
    for right in range(len(s)):
        # 1. Expand: Add s[right]
        # But first, shrink if it would cause duplicate
        
        # 2. Shrink: While s[right] already in window
        while s[right] in char_set:
            char_set.remove(s[left])
            left += 1
        
        # Now we can safely add s[right]
        char_set.add(s[right])
        
        # 3. Update result
        max_length = max(max_length, right - left + 1)
    
    return max_length
python

Why This Works:

  • The template handles the edge case of empty strings (loop never runs, returns 0)
  • No off-by-one errors (right - left + 1)
  • Clear separation: shrink until valid, then expand

Time Complexity: — each character is added once and removed once
Space Complexity: where is the character set size

Actionable Takeaways

  1. Memorize one template, not ten solutions: Pick the variable-size template in your preferred language and drill it until it's muscle memory.

  2. Identify the pattern before coding: Spend 30 seconds deciding: fixed or variable? What defines "invalid"? What's the result metric?

  3. Use the template as a checklist: Even if you don't copy it verbatim, mentally verify:

    • ✅ Expand captured in loop
    • ✅ Shrink in while (for variable) or if (for fixed)
    • ✅ Result updated after valid window established
  4. Practice the mapping: Take 5 sliding window problems and explicitly map them to the template:

  5. Internalize the invariant: "After the shrink loop, the window is always valid." This single rule prevents 90% of logic bugs.

FAQ

Q: Do I need to memorize templates for both fixed and variable sliding windows?
A: Yes, but they're structurally similar. The variable-size template is more general—once you have that down, the fixed-size version is just a simplification (no while loop, deterministic shrink).

Q: What if the problem asks for the minimum window instead of maximum?
A: Same template, just initialize result = float('inf') (or Integer.MAX_VALUE) and use min instead of max when updating.

Q: Can I use this template for "find all subarrays" problems?
A: Not directly. If you need to count or collect all valid windows (not just the longest/shortest), you'll need to modify the result update step to track each valid window.

Q: What about problems with negative numbers?
A: Sliding window works with negative numbers if you're not reasoning about sums. For subarray sum problems with negatives, use prefix sums instead. Learn more in our guide on when NOT to use sliding window.

Q: How do I handle the window state for complex conditions?
A: The window_state is a placeholder—replace it with whatever data structure fits. For character counts, use Map. For unique elements, use Set. For sum, use an int. The template structure stays the same.

Q: Should I explain the template to my interviewer?
A: Absolutely. Say: "I'm using a standard sliding window template—I'll expand the window, shrink when invalid, and track the maximum length." This shows structured thinking.

Ready to Practice This Pattern?

Apply this pattern with LeetCopilot's AI-powered hints, notes, and mock interviews. Transform your coding interview preparation today.

Related Tutorials