Topics
This technique uses a dynamic window [left, right] (often termed [tail, head]) that expands and contracts to find optimal subarrays or substrings satisfying certain conditions. Unlike sliding window with fixed window size, the size isn’t fixed.
Core Idea
- Expansion (head pointer): For a given
tailposition, theheadpointer expands the window (head++) as far as possible, adding elements one by one, as long as some condition is satisfied for the window[tail, head+1] - Processing: Once the
headpointer cannot expand further (either reaching the end or violating the condition), the current window[tail, head]represents the largest valid window starting attail. Process this window to update the answer (e.g., find max length, count valid windows) - Contraction (tail pointer): The
tailpointer moves one step forward (tail++) to explore the next potential starting position. Before the next expansion phase begins, we need to undo the “effect” of the oldtailposition (since it’s not part of current window)
This process repeats, iterating through all possible start positions and finding the maximal valid window for each.
Implementation
For a structured approach to implementing variable window sliding window, especially in competitive programming, consider using the snake framework. This framework provides a template with
check_condition,update_state, andundo_update_statefunctions to systematically handle window expansion and contraction.
Classic Examples
Given an array, find the longest subarray where the sum is less than or equal to k
- Use
tail = 0, head = -1andcurrent_sum = 0- Iterate with
tailfrom0ton-1:
- Expansion: While
head < n-1andcurrent_sum + arr[head + 1] <= k, incrementheadand addarr[head]tocurrent_sum- Processing: The maximal window starting at
tailwith sum<= kis[tail, head]. Updatemax_length = max(max_length, head - tail + 1)- Advance Tail: Subtract
arr[tail]fromcurrent_sumand incrementtail- Time: vs. brute-force .
Find the length of the longest substring without repeating characters.
- Use
tail = 0, head = -1and a frequency map/set (window_chars) for characters ins[tail...head].- Iterate with
tailfrom0ton-1:
- Expansion: While
head < n-1ands[head + 1]is not inwindow_chars, incrementheadand adds[head]towindow_chars- Processing: The maximal window starting at
tailwithout repeats is[tail, head]. Updatemax_length = max(max_length, head - tail + 1)- Advance Tail: Remove
s[tail]fromwindow_charsand incrementtail- Time: vs. brute-force
Given an array and a target sum k. Find the number of subarrays whose sum equals k.
Note: For arbitrary integers (including negatives), the prefix sum with hash map approach is generally preferred ( time, space). The sliding window approach below works efficiently for non-negative numbers.
- Use
tail = 0, head = -1andcurrent_sum = 0. Initializecount = 0- Iterate with
tailfrom0ton-1:
- Expansion: While
head < n-1andcurrent_sum + arr[head+1] <= k:
- Increment
headand addarr[head]tocurrent_sum- Processing: If
current_sum == k, incrementcount- Advance Tail: Subtract
arr[tail]fromcurrent_sumand incrementtail- Time: (for non-negative numbers)