Sliding Window Template

Sliding Window Cheatsheet Template :

Template 1: Sliding Window (Shrinkable)

Key Idea

  1. Start with an initial window [i, j] and expand it by incrementing j.

  2. Whenever the window becomes invalid, shrink it by incrementing i until it is valid again.

  3. Keep track of the maximum size of the valid window.

Why Use This Template?

This template is useful when you want to maximize the size of a valid window, and the window can shrink and grow dynamically depending on the condition.

import java.util.Arrays;

class Solution {

public int maxFrequency(int[] nums, int k) {

Arrays.sort(nums); // Sort the array

long sum = 0; // Track the sum of elements in the window

int i = 0, ans = 1; // Initialize pointers and result

for (int j = 0; j < nums.length; j++) {

sum += nums[j]; // Add the current number to the sum

// Shrink the window if invalid

while ((j - i + 1L) * nums[j] - sum > k) {

sum -= nums[i]; // Remove the leftmost element

i++; // Shrink the window from the left

}

// Update the maximum valid window size

ans = Math.max(ans, j - i + 1);

}

return ans;

}

}

Essentially, we want to keep the window valid at the end of each outer for loop.

Template 2: Sliding Window (Non-shrinkable)

Key Idea

  1. Expand the window by incrementing j.

  2. If the window becomes invalid, shift it forward by incrementing both i and j simultaneously.

  3. Keep track of the largest valid window encountered.

Why Use This Template?

This template works well for problems where the window can only grow when valid and must shift entirely when invalid.

import java.util.Arrays;

class Solution {

public int maxFrequency(int[] nums, int k) {

Arrays.sort(nums); // Sort the array

long sum = 0; // Track the sum of elements in the window

int i = 0, j = 0; // Initialize pointers

for (int j = 0; j < nums.length; j++) {

sum += nums[j]; // Add the current number to the sum

// Shift the window if invalid

if ((j - i + 1L) * nums[j] - sum > k) {

sum -= nums[i]; // Remove the leftmost element

i++; // Shift the window forward

}

}

return j - i; // Return the size of the largest valid window

}

}

For String Question Sliding window

class Solution {

public int solveStringProblem(String s, int k) {

// Step 1: Initialize necessary variables

int[] freq = new int[26]; // Array to store the frequency of characters (if needed)

int i = 0; // Left pointer of the sliding window

int result = 0; // Variable to store the final result (e.g., max length, count, etc.)

// Step 2: Iterate through the string with the right pointer

for (int j = 0; j < s.length(); j++) {

// Add the current character to the window

freq[s.charAt(j) - 'A']++;

// Step 3: Check if the current window is valid

while (/* Condition to check if the window is invalid */) {

// Shrink the window from the left

freq[s.charAt(i) - 'A']--;

i++;

}

// Step 4: Update the result based on the valid window

result = Math.max(result, j - i + 1); // Example: maximum window size

}

// Step 5: Return the result

return result;

}

}

When Two Substring is given

class Solution {

public int equalSubstring(String s, String t, int maxCost) {

// Step 1: Initialize necessary variables

int currentCost = 0; // Current total cost of the window

int i = 0; // Left pointer of the sliding window

int maxLength = 0; // Variable to store the maximum length of the valid substring

// Step 2: Iterate through the string with the right pointer

for (int j = 0; j < s.length(); j++) {

// Add the cost of transforming s[j] to t[j] to the current cost

currentCost += Math.abs(s.charAt(j) - t.charAt(j));

// Step 3: Shrink the window if the current cost exceeds maxCost

while (currentCost > maxCost) {

currentCost -= Math.abs(s.charAt(i) - t.charAt(i)); // Remove the cost of s[i] to t[i]

i++; // Shrink the window by moving the left pointer

}

// Step 4: Update the result based on the valid window

maxLength = Math.max(maxLength, j - i + 1);

}

// Step 5: Return the result

return maxLength;

}

}

Bit Wise Sliding Window

class Solution {

public int longestNiceSubarray(int[] nums) {

int currentOR = 0; // Tracks the bitwise OR of the current window

int i = 0; // Left pointer of the sliding window

int maxLength = 0; // Maximum length of a valid subarray

for (int j = 0; j < nums.length; j++) {

// While the new element violates the condition, shrink the window

while ((currentOR & nums[j]) != 0) {

currentOR ^= nums[i]; // Remove the leftmost element from currentOR

i++; // Move the left pointer

}

// Add the current element to currentOR

currentOR |= nums[j];

// Update the maximum length

maxLength = Math.max(maxLength, j - i + 1);

}

return maxLength;

}

}

Key Signs of Where Modifications Are Done:

  1. Initialization:

    • Define variables to track the window property (e.g., currentCost, freq[]).
  2. Expanding the Window:

    • Modify the tracked property for the element at j.
  3. Shrinking the Window:

    • Modify the tracked property for the element at i and move i forward.
  4. Result Update:

    • Optimize based on the valid window (e.g., Math.max, Math.min, or sum).

Key Differences Between Sorting and Count-Based Approaches

AspectSortingCounting/Frequency
Use CaseRelative order or value differences matter.Frequency or bounded distinct elements matter.
ComplexityO(nlog⁡n)O(n \log n)O(nlogn) due to sorting.O(n)O(n)O(n) (or O(n+k)O(n + k)O(n+k) with frequency array).
Window ConditionsDepends on sorted order of elements.Depends on frequency or counts of elements.
ExamplesMaximize sum with gaps, subsequence lengths.Substring properties, binary array problems.