Tutorials Logic, IN +91 8092939553 info@tutorialslogic.com
FAQs Support
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Interview Questions Website Development
Compiler Tutorials

Sliding Window Technique

What is the Sliding Window Technique?

The sliding window technique maintains a contiguous subarray (or substring) of variable or fixed size as a "window" that slides over the data. Instead of recomputing the entire window from scratch each time, you add the new element entering the window and remove the element leaving it � reducing O(n�) brute force to O(n).

Fixed vs Variable Window

TypeWindow SizeWhen to UseExample Problems
Fixed WindowConstant kMax/min/sum of subarray of size kMax sum subarray of size k, average of subarrays
Variable WindowGrows/shrinksFind smallest/largest window satisfying a conditionLongest substring without repeating chars, minimum window substring

When to Use Sliding Window

  • Problem involves a contiguous subarray or substring
  • You need to find max/min/sum/count within a window
  • The data structure is a linear sequence (array or string)
  • Brute force would be O(n�) or O(n�) � sliding window brings it to O(n)
Fixed Window � Maximum Sum Subarray of Size K
#include <iostream>
#include <vector>
using namespace std;

// Max sum subarray of size k � O(n) time, O(1) space
int maxSumSubarray(const vector<int>& arr, int k) {
    int n = arr.size();
    if (n < k) return -1;

    // Build first window
    int windowSum = 0;
    for (int i = 0; i < k; i++) windowSum += arr[i];

    int maxSum = windowSum;

    // Slide the window: add next element, remove first element
    for (int i = k; i < n; i++) {
        windowSum += arr[i] - arr[i - k];
        maxSum = max(maxSum, windowSum);
    }
    return maxSum;
}

int main() {
    vector<int> arr = {2, 1, 5, 1, 3, 2};
    cout << "Max sum (k=3): " << maxSumSubarray(arr, 3) << endl;  // 9 (5+1+3)

    vector<int> arr2 = {-1, 2, 3, -4, 5, 10};
    cout << "Max sum (k=2): " << maxSumSubarray(arr2, 2) << endl;  // 15 (5+10)
    return 0;
}
public class SlidingWindow {

    static int maxSumSubarray(int[] arr, int k) {
        int n = arr.length;
        if (n < k) return -1;

        int windowSum = 0;
        for (int i = 0; i < k; i++) windowSum += arr[i];

        int maxSum = windowSum;
        for (int i = k; i < n; i++) {
            windowSum += arr[i] - arr[i - k];
            maxSum = Math.max(maxSum, windowSum);
        }
        return maxSum;
    }

    public static void main(String[] args) {
        int[] arr = {2, 1, 5, 1, 3, 2};
        System.out.println("Max sum (k=3): " + maxSumSubarray(arr, 3));  // 9

        int[] arr2 = {-1, 2, 3, -4, 5, 10};
        System.out.println("Max sum (k=2): " + maxSumSubarray(arr2, 2)); // 15
    }
}
# Max sum subarray of size k � O(n) time, O(1) space
def max_sum_subarray(arr, k):
    n = len(arr)
    if n < k: return -1

    window_sum = sum(arr[:k])  # first window
    max_sum = window_sum

    for i in range(k, n):
        window_sum += arr[i] - arr[i - k]  # slide: add new, remove old
        max_sum = max(max_sum, window_sum)

    return max_sum

arr = [2, 1, 5, 1, 3, 2]
print("Max sum (k=3):", max_sum_subarray(arr, 3))  # 9 (5+1+3)

arr2 = [-1, 2, 3, -4, 5, 10]
print("Max sum (k=2):", max_sum_subarray(arr2, 2)) # 15 (5+10)
// Max sum subarray of size k � O(n) time, O(1) space
function maxSumSubarray(arr, k) {
    const n = arr.length;
    if (n < k) return -1;

    let windowSum = arr.slice(0, k).reduce((a, b) => a + b, 0);
    let maxSum = windowSum;

    for (let i = k; i < n; i++) {
        windowSum += arr[i] - arr[i - k];  // slide: add new, remove old
        maxSum = Math.max(maxSum, windowSum);
    }
    return maxSum;
}

console.log("Max sum (k=3):", maxSumSubarray([2,1,5,1,3,2], 3));   // 9
console.log("Max sum (k=2):", maxSumSubarray([-1,2,3,-4,5,10], 2)); // 15

Variable Window � Longest Substring Without Repeating Characters

Longest Substring Without Repeating Characters and Minimum Window Substring
#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;

// Longest substring without repeating characters � O(n)
int lengthOfLongestSubstring(const string& s) {
    unordered_map<char, int> lastSeen;
    int maxLen = 0, left = 0;
    for (int right = 0; right < s.size(); right++) {
        if (lastSeen.count(s[right]) && lastSeen[s[right]] >= left) {
            left = lastSeen[s[right]] + 1;  // shrink window
        }
        lastSeen[s[right]] = right;
        maxLen = max(maxLen, right - left + 1);
    }
    return maxLen;
}

// Minimum window substring � O(n + m)
string minWindow(const string& s, const string& t) {
    unordered_map<char, int> need, have;
    for (char c : t) need[c]++;
    int formed = 0, required = need.size();
    int lo = 0, minLen = INT_MAX, start = 0;
    for (int hi = 0; hi < s.size(); hi++) {
        have[s[hi]]++;
        if (need.count(s[hi]) && have[s[hi]] == need[s[hi]]) formed++;
        while (formed == required) {
            if (hi - lo + 1 < minLen) { minLen = hi - lo + 1; start = lo; }
            have[s[lo]]--;
            if (need.count(s[lo]) && have[s[lo]] < need[s[lo]]) formed--;
            lo++;
        }
    }
    return minLen == INT_MAX ? "" : s.substr(start, minLen);
}

int main() {
    cout << lengthOfLongestSubstring("abcabcbb") << endl;  // 3 ("abc")
    cout << lengthOfLongestSubstring("pwwkew") << endl;    // 3 ("wke")
    cout << minWindow("ADOBECODEBANC", "ABC") << endl;     // "BANC"
    return 0;
}
import java.util.HashMap;

public class VariableWindow {

    static int lengthOfLongestSubstring(String s) {
        HashMap<Character, Integer> lastSeen = new HashMap<>();
        int maxLen = 0, left = 0;
        for (int right = 0; right < s.length(); right++) {
            char c = s.charAt(right);
            if (lastSeen.containsKey(c) && lastSeen.get(c) >= left) {
                left = lastSeen.get(c) + 1;
            }
            lastSeen.put(c, right);
            maxLen = Math.max(maxLen, right - left + 1);
        }
        return maxLen;
    }

    static String minWindow(String s, String t) {
        HashMap<Character, Integer> need = new HashMap<>(), have = new HashMap<>();
        for (char c : t.toCharArray()) need.merge(c, 1, Integer::sum);
        int formed = 0, required = need.size(), lo = 0, minLen = Integer.MAX_VALUE, start = 0;
        for (int hi = 0; hi < s.length(); hi++) {
            char c = s.charAt(hi);
            have.merge(c, 1, Integer::sum);
            if (need.containsKey(c) && have.get(c).equals(need.get(c))) formed++;
            while (formed == required) {
                if (hi - lo + 1 < minLen) { minLen = hi - lo + 1; start = lo; }
                char lc = s.charAt(lo);
                have.merge(lc, -1, Integer::sum);
                if (need.containsKey(lc) && have.get(lc) < need.get(lc)) formed--;
                lo++;
            }
        }
        return minLen == Integer.MAX_VALUE ? "" : s.substring(start, start + minLen);
    }

    public static void main(String[] args) {
        System.out.println(lengthOfLongestSubstring("abcabcbb"));  // 3
        System.out.println(minWindow("ADOBECODEBANC", "ABC"));     // BANC
    }
}
from collections import defaultdict

# Longest substring without repeating characters � O(n)
def length_of_longest_substring(s):
    last_seen = {}
    max_len = left = 0
    for right, c in enumerate(s):
        if c in last_seen and last_seen[c] >= left:
            left = last_seen[c] + 1  # shrink window
        last_seen[c] = right
        max_len = max(max_len, right - left + 1)
    return max_len

# Minimum window substring � O(n + m)
def min_window(s, t):
    need = defaultdict(int)
    for c in t: need[c] += 1
    have = defaultdict(int)
    formed = required = len(need)
    lo = min_len = float('inf')
    start = 0
    lo = 0
    for hi, c in enumerate(s):
        have[c] += 1
        if need[c] and have[c] == need[c]: formed -= 1
        while formed == 0:
            if hi - lo + 1 < min_len:
                min_len = hi - lo + 1
                start = lo
            have[s[lo]] -= 1
            if need[s[lo]] and have[s[lo]] < need[s[lo]]: formed += 1
            lo += 1
    return s[start:start + min_len] if min_len != float('inf') else ""

print(length_of_longest_substring("abcabcbb"))  # 3 ("abc")
print(length_of_longest_substring("pwwkew"))    # 3 ("wke")
print(min_window("ADOBECODEBANC", "ABC"))       # "BANC"
// Longest substring without repeating characters � O(n)
function lengthOfLongestSubstring(s) {
    const lastSeen = new Map();
    let maxLen = 0, left = 0;
    for (let right = 0; right < s.length; right++) {
        const c = s[right];
        if (lastSeen.has(c) && lastSeen.get(c) >= left) {
            left = lastSeen.get(c) + 1;  // shrink window
        }
        lastSeen.set(c, right);
        maxLen = Math.max(maxLen, right - left + 1);
    }
    return maxLen;
}

// Minimum window substring � O(n + m)
function minWindow(s, t) {
    const need = new Map(), have = new Map();
    for (const c of t) need.set(c, (need.get(c) || 0) + 1);
    let formed = 0, required = need.size;
    let lo = 0, minLen = Infinity, start = 0;
    for (let hi = 0; hi < s.length; hi++) {
        const c = s[hi];
        have.set(c, (have.get(c) || 0) + 1);
        if (need.has(c) && have.get(c) === need.get(c)) formed++;
        while (formed === required) {
            if (hi - lo + 1 < minLen) { minLen = hi - lo + 1; start = lo; }
            const lc = s[lo];
            have.set(lc, have.get(lc) - 1);
            if (need.has(lc) && have.get(lc) < need.get(lc)) formed--;
            lo++;
        }
    }
    return minLen === Infinity ? "" : s.slice(start, start + minLen);
}

console.log(lengthOfLongestSubstring("abcabcbb"));  // 3
console.log(minWindow("ADOBECODEBANC", "ABC"));     // "BANC"

Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.