Fixed Window
while expand
Naïve Sum/Average
Max Sum Subarray of size K
The objective is to find the maximum sum of all contiguous subarrays of length K in a given array. This problem can be efficiently solved by employing the sliding window technique to maintain the sum of elements within the current window, subsequently finding the maximum sum.
Expansion:
- Incrementally add each element's value to a running total as the
rightpointer advances, until the window reaches the desired sizeK. - This phase accumulates the initial sum required to compute the first potential maximum sum.
Logic:
- Compare the current window's sum with the maximum sum recorded so far and update the maximum sum if the current window's sum is greater.
Shrinking:
- Before advancing the window, subtract the element at the left edge of the window from the total sum.
- Increment the
leftpointer to slide the window one position to the right, preparing for the next window's sum calculation.
- Time
- O(N)
Nis the total number of elements in the array.- The algorithm ensures each element is added and subtracted exactly once, resulting in linear time complexity.
- Space
- O(1)
- The space complexity is constant as the solution utilizes a fixed number of variables, irrespective of the input array's size.
643. Maximum Average Subarray I
The goal is to find the maximum average value of all contiguous subarrays of length k. The sliding window technique maintains the running sum of the current window, then calculates its average -- avoiding recomputation across overlapping windows.
Expansion:
- Iterate through the array using a
rightpointer, adding each element's value to the total sum until the window reaches sizek. - This step builds up the initial sum required to calculate the first average.
Logic:
- Calculate the average of the current window by dividing the total sum by
k. - Update
maxiif the current window's average is higher.
Shrinking:
- Before moving the window forward, subtract the element at the left edge from the total sum.
- Increment the
leftpointer to slide the window one position to the right.
- Time
- O(N)
Nis the number of elements in the input array.- Each element is processed exactly once, making the algorithm linear time.
- Space
- O(1)
- Only a fixed number of variables are used, independent of the input array size.
1343. Number of Sub-arrays of Size K and Average Greater than or Equal to Threshold
The challenge is to count contiguous subarrays of length k whose average is greater than or equal to a given threshold. The sliding window technique maintains the running sum to evaluate each window's average in O(1) per step.
Expansion:
- Iterate through the array using a
rightpointer, adding each element's value to a running total until the window attains sizek. - This step accumulates the sum needed to evaluate the first average.
Logic:
isAboveThreshold()determines if the current window's average meets or exceedsthreshold.- If it does, increment
count.
Shrinking:
- Before advancing the window, subtract the leftmost element's value from the total sum.
- Increment the
leftpointer to shift the window one position to the right.
- Time
- O(N)
Nis the number of elements in the input array.- Each element is added and removed from the window exactly once.
- Space
- O(1)
- Only a fixed number of variables are used regardless of input size.
2090. K Radius Subarray Averages
For each index i, the result is the integer average of the 2*k+1 elements centered at i. If fewer than k elements exist on either side, result stays -1. A fixed window of size w = 2*k+1 slides across nums, writing the floor-average to the center position on every valid window.
Expansion:
- Advance
rightuntil the window reaches sizew, accumulating the runningtotal.
Logic:
- If
right - left == w, the window is full. Computeresult[left + k] = total // w.
Shrinking:
- Drop
nums[left]fromtotaland advanceleftto slide the window forward.
- Time
- O(N)
Nis the number of elements innums.- Each element is added to and removed from the window exactly once.
- Space
- O(N)
- The
resultarray has the same length asnums.
1423. Maximum Points You Can Obtain from Cards
Choosing k cards from either end is equivalent to leaving a contiguous subarray of size n - k in the middle. Finding the maximum score from the ends becomes finding the minimum sum of any window of size w = n - k, then subtracting that from the total sum.

Expansion:
- Advance
rightuntil the window reaches sizew, accumulatingtotal.
Logic:
mini = min(mini, total)-- track the smallest window sum seen so far.
Shrinking:
- Drop
cardPoints[left]fromtotaland advanceleft, sliding the window forward.
The answer is arr_total - mini.
- Time
- O(2N)
Nis the total number of cards.arr_total = sum(cardPoints)is oneO(N)pass, then the sliding window makes a secondO(N)pass, adding and removing each card exactly once - two distinctO(N)passes,2N.- Space
- O(1)
- Only a fixed number of variables are used regardless of input size.
1176. Diet Plan Performance
A fixed window of size k slides across calories, keeping a running total. After each window fills, a compare lambda scores it against [lower, upper] and adds +1, 0, or -1 to points. The window then shrinks by one from the left.
With calories=[2,6,4,1,1], k=2, lower=3, upper=5:
[2,6]→ total8 > 5→+1(exceed)[6,4]→ total10 > 5→+1(exceed)[4,1]→ total5 ∈ [3,5]→0(in range)[1,1]→ total2 < 3→-1(deficit)
Result: points = 1
- Time
- O(N)
Nis the length ofcalories(5in the example above).- Each element is added once when
rightexpands into it and removed once whenleftshrinks past it --calories[0]=2enters at step 1, leaves at step 5. - Space
- O(1)
- Only scalar variables
left,right,total,pointsare kept -- no auxiliary array regardless of input size.
1052. Grumpy Bookstore Owner
total starts as the sum of all customers during non-grumpy minutes -- these are always satisfied regardless of the technique. The sliding window of size minutes moves across the array; within it, grumpy minutes contribute their customers via getGrumpyScore, temporarily boosting total. maxi tracks the best combined score seen as the window slides.
Expansion:
- Advance
rightuntil the window reachesminutesin width, addinggetGrumpyScore(right) = customers[right] × grumpy[right]tototal. Non-grumpy minutes contribute 0 (already in the base).
Logic:
maxi = max(maxi, total)-- record the highest total achievable with the window at this position.
Shrinking:
- Remove the leftmost element's grumpy bonus (
getGrumpyScore(left)) before advancingleft. Ifgrumpy[left] = 0, this is 0 andtotalis unchanged.
- Time
- O(2N)
Nis the number of minutes (length ofcustomers/grumpy).- The initial base
totalis computed in oneO(N)pass overzip(customers, grumpy), then the sliding window makes a secondO(N)pass, adding and removing each element exactly once - two distinctO(N)passes,2N. - Space
- O(1)
- Only a fixed number of scalar variables are used regardless of input size.
1652. Defuse the Bomb
1652Defuse the Bomb
The bomb is a circular array: replacing each code[i] with the sum of the next k (or previous |k|) elements. Because the array is circular, indices wrap around using right % n. A single fixed window of size |k| slides across the extended range [0, n + |k| - 1), keeping a running total.
negative distinguishes the two directions. getPosition maps the current window back to the result index being filled: for forward k, the target is the element just before the window ((left-1) % n); for backward k, it's the element just after the window (right % n).
Expansion:
- Advance
rightuntil the window reaches size|k|, accumulatingtotalusingcode[right % n]to handle the circular wrap.
Logic:
result[getPosition()] = total-- write the current window sum into the correct result index.
Shrinking:
- Subtract
code[left]fromtotaland advanceleftto slide the window one step forward.
- Time
- O(N)
Nis the length ofcode.- The outer loop runs exactly
Ntimes (one window position per result element). Each element is added once during expansion and removed once during shrinking. - Space
- O(N)
- The
resultarray has the same length ascode. All other variables are scalar.
Hashmap
187. Repeated DNA Sequences
A fixed window of size k = 10 slides over s. The window expands by advancing right until right - left == 10, then substring = s[left:right] is extracted and looked up in counter. When a sequence's count reaches exactly 2 it is added to result -- subsequent occurrences are silently skipped because the condition checks == 2 not >= 2. left increments to slide the window one position forward.
Expansion:
- Advance
rightuntilright - left == k. No element value is read during expansion -- the window boundary is all that matters.
Logic:
- Extract
substring = s[left:right], incrementcounter[substring], and append toresultonly when the count becomes exactly2.
Shrinking:
- Increment
leftto slide the window forward, discarding the leftmost character.
- Time
- O(N)
Nis the length ofs.- Each character is entered and exited the window exactly once. The substring slice
s[left:right]costs O(k) = O(10) = O(1) per window, so the total is O(N). - Space
- O(N)
countermay hold up toN - k + 1distinct substrings of lengthk. Each key is O(k) = O(10) bytes, giving O(N) overall.
Hashmap - Duplicate Elements
219. Contains Duplicate II
containsDuplicatesInK is the reusable primitive: a fixed-window sliding window that returns True as soon as any value appears more than once within a window of size k. The check fires inside the expansion loop -- counter[arr[right]] is incremented first, then immediately tested, so the algorithm short-circuits the moment a duplicate is confirmed.
containsNearbyDuplicate adapts it to LC 219 by adjusting k = k + 1 before the call. The +1 accounts for the inclusive bound -- abs(i - j) <= k allows indices exactly k apart, which requires a window of size k + 1.
Expansion:
- Increment
counter[arr[right]], then check if it exceeds 1 before advancingright.
Logic (inline):
if counter[arr[right]] > 1: return True-- fires as soon as any value is seen twice within the window.
Shrinking:
- Decrement
counter[arr[left]]and advanceleftto slide the window forward.
- Time
- O(n)
nis the length ofnums(arrinsidecontainsDuplicatesInK).- Each element enters the counter once in the expansion loop and exits once in the shrinking step, so total work is
O(n). - Space
- O(k)
- The counter holds at most
k + 1entries at any time -- one per element in the current window.
217. Contains Duplicate
Reuses containsDuplicatesInK with k = len(nums) so the window covers the entire array. Any duplicate anywhere in the array triggers an early return.
- Time
- O(N)
- Each element is added to and removed from the counter at most once as the window slides.
- Space
- O(N)
- The counter stores at most N distinct elements.
Hashmap - Unique/Distinct Elements
1876. Substrings of Size Three with Distinct Characters
Count all substrings of length 3 that contain distinct characters. A fixed window of size k = 3 slides across the string, using a custom Counter that tracks the number of distinct keys in O(1) via __setitem__.
Custom Counter:
self.distinctis maintained incrementally: incremented when a key transitions from≤0 → >0(new distinct character appears), decremented when it transitions from>0 → ≤0(character leaves the window). All other transitions leavedistinctunchanged.- This means
counter.distinct_count()is always the count of keys with a non-zero value - nodelneeded on shrink.
Expansion:
- Advance
right, incrementingcounter[s[right]]until the window reaches sizek.
Logic:
isGoodSubstringchecks ifcounter.distinct_count() == k. If so, incrementgood_substrings.
Shrinking:
- Decrement
counter[s[left]]. The__setitem__hook handles the1 → 0transition automatically.
- Time
- O(N)
- Each character is processed at most twice (once when entering and once when leaving the window).
- Space
- O(1)
- The hashmap's size is constrained by the window size (
k = 3).
1852. Distinct Numbers in Each Subarray
Calculate the number of distinct integers in every subarray of size k. A fixed window slides across nums, using a custom Counter that tracks distinct key count in O(1) via __setitem__. The number of unique elements (counter.distinct_count()) is appended to result for each window position.
Custom Counter:
self.distinctincrements on≤0 → >0transitions and decrements on>0 → ≤0transitions. Negative values do not count, socounter.distinct_count()is always the count of keys with strictly positive frequency - no explicitdelneeded.
Expansion:
- Advance
right, incrementingcounter[nums[right]]until the window reaches sizek.
Logic:
- Append
counter.distinct_count()toresult.
Shrinking:
- Decrement
counter[nums[left]]. The__setitem__hook handles the1 → 0transition automatically.
- Time
- O(N)
- Each element enters and exits the window exactly once.
- Space
- O(k)
- The hashmap holds at most
kdistinct elements.
2107. Number of Unique Flavors After Sharing K Candies
Determine the maximum number of unique candy flavors remaining after giving away exactly k consecutive candies. A custom Counter is initialized with all of candies, then the sliding window of size k represents the shared portion - decrement as candies enter the window, increment as they leave.
Custom Counter:
- Initialized with
Counter(candies)so all flavors start with their full frequencies. self.distincttracks the number of keys with strictly positive count, updated automatically on≤0 ↔ >0transitions in__setitem__. No explicitdelis ever needed.
Expansion:
- Decrement
counter[candies[right]]as each candy enters the sharing window. The1 → 0transition automatically reducescounter.distinct_count().
Logic:
counter.distinct_count()is the number of unique flavors the keeper retains. Track the maximum.
Shrinking:
- Increment
counter[candies[left]]as each candy leaves the sharing window. The0 → 1transition automatically increasescounter.distinct_count().
- Time
- O(N)
- Single pass through the candies array with counter modifications.
- Space
- O(N)
- The counter may contain every unique candy flavor.
1100. Find K-Length Substrings With No Repeated Characters
Count all k-length substrings of s that consist entirely of unique characters. A fixed window of size k slides across the string using a custom Counter that tracks distinct key count in O(1) via __setitem__. A substring is valid when counter.distinct_count() == k.
Custom Counter:
self.distinctincrements on≤0 → >0transitions and decrements on>0 → ≤0transitions, socounter.distinct_count()is always the count of keys with strictly positive frequency - no explicitdelneeded.
Expansion:
- Advance
right, incrementingcounter[s[right]]until the window reaches sizek.
Logic:
isDistinctchecks ifcounter.distinct_count() == k. If so, incrementans.
Shrinking:
- Decrement
counter[s[left]]. The__setitem__hook handles the1 → 0transition automatically.
- Time
- O(n)
- Each of the
ncharacters insis added to and removed fromcounteronce asrightandlefteach sweep across the string. - Space
- O(k)
- The hashmap holds at most
kentries.
Substrings of length k with k-1 distinct elements
Count all substrings of length k that contain exactly k - 1 distinct characters - meaning exactly one character appears twice in the window. A custom Counter tracks distinct key count in O(1) via __setitem__. A window is valid when counter.distinct_count() == k - 1.
Custom Counter:
self.distinctincrements on≤0 → >0transitions and decrements on>0 → ≤0transitions, socounter.distinct_count()always reflects strictly positive keys - no explicitdelneeded.
Expansion:
- Advance
right, incrementingcounter[s[right]]until the window reaches sizek.
Logic:
- Check if
counter.distinct_count() == k - 1. If so, incrementans.
Shrinking:
- Decrement
counter[s[left]]. The__setitem__hook handles the1 → 0transition automatically.
- Time
- O(n)
rightadvances throughsonce in the expansion loop andleftadvances once per outer iteration in the shrinking step, each doingO(1)counter work (__setitem__), so total isO(n), wheren = len(s).- Space
- O(k)
counter.counterholds at mostkcharacters, one per element in the current window of sizek.
2461. Maximum Sum of Distinct Subarrays With Length K
Find the maximum sum among all subarrays of size k whose elements are all distinct. A fixed window slides across nums, maintaining a running total of the window's sum and a custom Counter that tracks distinct key count in O(1) via __setitem__. A window of size k has all-distinct elements exactly when counter.distinct_count() == k.
Custom Counter:
self.distinctincrements on≤0 → >0transitions and decrements on>0 → ≤0transitions, socounter.distinct_count()always reflects strictly positive keys - no explicitdelneeded.
Expansion:
- Advance
right, incrementingcounter[nums[right]]and adding tototaluntil the window reaches sizek.
Logic:
- If
isUnique()(allkelements distinct), updatemaxi = max(maxi, total).
Shrinking:
- Decrement
counter[nums[left]]and subtract fromtotal. The__setitem__hook handles the1 → 0transition automatically.
- Time
- O(n)
nis the length ofnums-leftandrighteach advance at mostntimes across the run, so every element enters and exits the window exactly once.- Space
- O(k)
counterholds at mostkdistinct elements, since the window never exceeds sizek.
2841. Maximum Sum of Almost Unique Subarray
Find the maximum sum among all subarrays of size k that are almost unique - containing at least m distinct elements. A fixed window slides across nums, maintaining a running total of the window's sum and a custom Counter that tracks distinct key count in O(1) via __setitem__. A window qualifies when counter.distinct_count() >= m.
This is the >= m relaxation of 2461. Maximum Sum of Distinct Subarrays With Length K, which demands all k elements be distinct (== k).
Custom Counter:
self.distinctincrements on≤0 → >0transitions and decrements on>0 → ≤0transitions, socounter.distinct_count()always reflects strictly positive keys - no explicitdelneeded.
Expansion:
- Advance
right, incrementingcounter[nums[right]]and adding tototaluntil the window reaches sizek.
Logic:
- If
isAlmostUnique()(at leastmdistinct elements), updatemaxi = max(maxi, total).
Shrinking:
- Decrement
counter[nums[left]]and subtract fromtotal. The__setitem__hook handles the1 → 0transition automatically.
- Time
- O(N)
- Each element enters and exits the window exactly once.
- Space
- O(k)
- The hashmap holds at most
kdistinct elements.
1297. Maximum Number of Occurrences of a Substring
Return the maximum number of occurrences of any substring of s that has at most maxLetters distinct characters and a length between minSize and maxSize.
Key insight - maxSize is a red herring; only minSize matters. We never need to look at substrings longer than minSize. Here is why, in two steps:
-
A longer valid substring can never out-count its shorter slices. Take any valid substring
tof lengthLwhereminSize < L <= maxSize. Slide a window of sizeminSizeinsidet: every such slicet'is also valid (it is shorter, so it has≤ maxLettersdistinct characters - shrinking a window can only lose distinct characters, never gain them) and it is contained int. Every timetappears ins, that same slicet'appears too - socount(t') ≥ count(t). A longer substring can therefore never beat the bestminSizesubstring. -
Shorter than
minSizeis disallowed, sominSizeis exactly the sweet spot: short enough to maximize repeats, long enough to be legal. We fixk = minSizeand ignoremaxSizeentirely.
Worked example. s = "aababcaab", maxLetters = 2, minSize = 3, maxSize = 4.
- The length-4 substring
"aaba"is valid (2 distinct:a,b) and occurs once. - Its length-3 prefix
"aab"is also valid and occurs twice (positions 0 and 6). - So the longer window
"aaba"(count 1) is strictly dominated by the shorter"aab"(count 2). Scanning onlyk = minSize = 3windows finds the answer 2 without ever materializing a length-4 window.
A custom Counter tracks distinct character count in O(1) via __setitem__. A defaultdict records how many times each length-k substring appears.
Custom Counter:
self.distinctincrements on≤0 → >0transitions and decrements on>0 → ≤0transitions, socounter.distinct_count()always reflects strictly positive keys - no explicitdelneeded.
Expansion:
- Advance
right, incrementingcounter[s[right]]until the window reaches sizek.
Logic:
- If
counter.distinct_count() <= maxLetters, record the substrings[left:right]insubstringsand updatemaxi.
Shrinking:
- Decrement
counter[s[left]]. The__setitem__hook handles the1 → 0transition automatically.
- Time
- O(N·k)
- Each of the
Nwindows slices a length-ksubstring (s[left:right]) and hashes it into the map. - Space
- O(N·k)
- The
substringsmap can hold up toNdistinct length-kkeys.
Hashmap - Anagrams/Permutations
438. Find All Anagrams in a String
Find all start indices of p's anagrams in s. A single custom Counter is initialized with p's character frequencies. The sliding window of size k = len(p) decrements the counter as chars enter and increments as they leave. When counter.distinct_count() == 0, all of p's frequency needs are exactly satisfied - the window is an anagram.
Custom Counter:
self.distincttracks the count of keys with positive (unsatisfied) frequency. Keys going negative (char in window but not inp, or over-represented) do not affectdistinct. An anagram occurs whencounter.distinct_count() == 0- no unsatisfied needs remain.
Expansion:
- Decrement
counter[s[right]]as each char enters the window, consuming fromp's frequency pool.
Logic:
isAnagramchecks ifcounter.distinct_count() == 0. If so, appendlefttoans.
Shrinking:
- Increment
counter[s[left]]as the leftmost char leaves the window, returning it to the pool.
- Time
- O(n)
- Each character of
s(lengthn) is processed once byright, and once more byleft-counterlookups/updates areO(26) = O(1)for the lowercase alphabet. - Space
- O(1)
counteris bounded by the alphabet size (26 lowercase letters), independent ofn.
242. Valid Anagram
Two strings s and t are anagrams if s contains an anagram of t spanning its entire length. Reuse findAnagrams(s, t) -- if it returns [0], the entire string s is an anagram of t.
- Time
- O(n)
findAnagramsscans throughs(lengthn) once with a sliding window matchingt's character frequency.- Space
- O(1)
- Fixed-size data structures for character frequency tracking.
567. Permutation in String
Determine if s1 is a permutation of any substring in s2. This is searching for an anagram of s1 within s2 -- directly addressed by findAnagrams. If the result is non-empty, a permutation exists.
- Time
- O(N)
findAnagramsiterates throughs2with a sliding window of sizelen(s1).- Space
- O(1)
- Fixed-size structures for character frequency tracking.
Count
2379. Minimum Recolors to Get K Consecutive Black Blocks
Find the minimum number of white blocks ('W') that need to be recolored to achieve k consecutive black blocks. A fixed window of size k slides across blocks, counting white blocks within each window. The minimum white count across all windows equals the minimum recolors needed.
Expansion:
- Advance
right, incrementingwhitesfor each 'W' until the window reaches sizek.
Logic:
mini = min(mini, whites)-- track the fewest white blocks in any window.
Shrinking:
- Decrement
whitesif the leftmost block is 'W', then advanceleft.
- Time
- O(N)
rightandlefteach advance acrossblocksonce, adding and removing each of theNblocks exactly once.- Space
- O(1)
- Only
left,right,mini, andwhitesare tracked, regardless ofN.
1456. Maximum Number of Vowels in a Substring of Given Length
Find the maximum number of vowels in any substring of length k. A fixed window slides across s, counting vowels within each window.
Expansion:
- Advance
right, incrementingcountfor each vowel until the window reaches sizek.
Logic:
maxi = max(maxi, count)-- track the highest vowel count.
Shrinking:
- Decrement
countif the leftmost character is a vowel, then advanceleft.
- Time
- O(n)
- Single pass through the string of length
nwith constant-time operations per character. - Space
- O(1)
- Fixed-size vowel set and scalar variables.
Count - Math
1550. Three Consecutive Odds
Determine if arr contains three consecutive odd numbers. A fixed window of size k = 3 slides across the array, maintaining a count of odd numbers. If the count equals k, three consecutive odds are found.
Expansion:
- Advance
right, incrementingoddsfor each odd number until the window reaches size 3.
Logic:
- If
odds == k, returnTrue.
Shrinking:
- Decrement
oddsif the leftmost number is odd, then advanceleft.
- Time
- O(n)
nis the length ofarr-leftandrighteach advance at mostntimes across the run, so the array is scanned once.- Space
- O(1)
- Only
left,right, andoddsare tracked, regardless of array length.
2269. Find the K-Beauty of a Number
Count how many substrings of length k within num are divisors of num. A fixed window of size k slides across the digits, building the sub-number by appending digits during expansion and trimming via modulo during shrinking. Digits are extracted by converting num to a digits list using [int(d) for d in str(num)].
Expansion:
- Append
digits[right]tosub_numby computingsub_num = sub_num * 10 + digits[right].
Logic:
isDivisiblechecks ifsub_num != 0andnum % sub_num == 0. If so, incrementans.
Shrinking:
sub_num = sub_num % (10 ** (k - 1))removes the leftmost digit.
- Time
- O(N)
Nis the number of digits innum. Each digit is processed once.- Space
- O(1)
- Digits are extracted directly via arithmetic; no array allocation needed.
Count - Swaps
1151. Minimum Swaps to Group All 1's Together
Find the minimum swaps to group all 1's together. The window size k equals the total count of 1's in the array. The minimum number of zeros within any window of that size equals the minimum swaps needed, since each zero represents a swap.
Expansion:
- Advance
right, counting zeros until the window reaches sizek.
Logic:
mini = min(mini, zeros)-- the fewest zeros in any window is the answer.
Shrinking:
- Decrement
zerosif the leftmost element is 0, then advanceleft.
- Time
- O(2n)
data.count(1)makes oneO(n)pass to findk.- The
while right < nloop makes a secondO(n)pass, sinceleftandrighteach advance at mostntimes -n + ncollapses to2n. - Space
- O(1)
- Constant space for tracking
zeroes,mini, and the window boundaries.
2134. Minimum Swaps to Group All 1's Together II
Extends "1151. Minimum Swaps to Group All 1's Together" to a circular array. n is set to 2 * len(nums) − 1 so right traverses all cyclic starting positions; isZero(i) wraps via nums[i % len(nums)].
Expansion:
- Advance
right, counting zeroes viaisZero(right)(wraps with%) until the window reaches sizek.
Logic:
mini = min(mini, zeroes)- minimum zeroes across all circular windows.
Shrinking:
- Decrement zeroes via
isZero(left), then advanceleft.
- Time
- O(n)
n = 2 * len(nums) - 1, the number of circular starting positions.rightadvances from0tonin the expansion loop andlefttrails it in the shrink step, so each index is visited once -O(n), still linear inlen(nums).- Space
- O(1)
- Only the scalars
left,right,zeroes, andminiare tracked; nothing scales withn.
Heap
239. Sliding Window Maximum
Find the maximum value in each sliding window of size k. A max heap stores elements as (value, index), so the heap top is always the largest value. Stale entries that have fallen outside the window are lazily discarded from the top.
Expansion:
- While the window has fewer than
kelements, push(nums[right], right)onto the heap and advanceright.
Logic:
result.append(heap[0][0])- the heap top is the current window's maximum (after stale entries are purged).
Shrinking:
- Advance
left, then pop from the top whileheap[0][1] < left(the maximum has left the window).
- Time
- O(N log N)
- Each of the
Nelements is pushed ontoheapexactly once viaheappush_max, and popped at most once viaheappop_max; but stale entries buried below the top are only removed once they bubble up to become the max, soheapcan hold up toNentries, making each push/popO(log N). - Space
- O(N)
heapcan grow to hold up toNentries, since a stale (out-of-window) entry is only cleaned up once it reaches the top;resultholdsN - k + 1values, which does not exceedN.
Deque
First negative in every window of size k
For each window of size k, report the first negative integer, or 0 if the window has none. A deque holds (index, value) pairs for the negatives currently inside the window, in order of arrival, so negatives[0] is always the earliest negative still in the window.
Expansion:
- Advance
rightuntil the window reaches sizek, appending(right, arr[right])to the deque wheneverarr[right] < 0.
Logic:
negatives[0][1]is the first negative in the window; append it toresult, or0if the deque is empty.
Shrinking:
- If the front's index equals
left, that negative is leaving the window - pop it from the front. Incrementleft.
- Time
- O(n)
n = len(arr). Each index is appended to and popped fromnegativesat most once, andright/lefteach advance across the array once - a singleO(n)pass.- Space
- O(k + n)
negativesholds at mostkentries, one per negative currently in the window.resultholds one entry per window,n - k + 1in total -O(n).
Sorting
1984. Minimum Difference Between Highest and Lowest of K Scores
Find the minimum difference between the highest and lowest scores in any subset of k scores. After sorting, the problem reduces to finding the smallest window of size k where nums[right-1] - nums[left] is minimized.
Expansion:
- Advance
rightuntil the window reaches sizek. No running total needed since the array is sorted.
Logic:
mini = min(mini, nums[right - 1] - nums[left])-- the difference between the window's endpoints.
Shrinking:
- Advance
leftto slide the window forward.
- Time
- O(n + n log n)
- A single
O(n)sliding-window pass, plusO(n log n)to sortnumsfirst -n + n log n. - Space
- O(sort)
left,right, andminiare scalars; the only space beyond the input is the sort's own working memory.- Sorting algorithms are typically
O(log n)space (in-place, recursion stack only), but Python'slist.sort()is Timsort, which allocates up toO(n)auxiliary space in the worst case - that's whatsortstands for here.
Bit Manipulation
3023. Find Pattern in Infinite Stream I
Find the starting index of a binary pattern within an infinite stream of bits. The pattern is converted to an integer pattern_num. A sliding window of bit-length k maintains the current sequence as an integer stream_num, built by left-shifting and appending each new bit. mask = 1 << (k - 1) is precomputed to isolate the most significant bit of the window.
Expansion:
stream_num = stream_num << 1 | stream.next()-- shift left and append the next bit until the window reacheskbits.
Logic:
- If
stream_num == pattern_num, returnleftas the starting index.
Shrinking:
- Remove the most significant bit:
stream_num = (stream_num | mask) ^ mask. This sidesteps Python's two's complement behavior compared to& ~mask.
- Time
- O(N)
- Linear in the number of bits read until the pattern is found.
- Space
- O(1)
- Constant number of integer variables.
3037. Find Pattern in Infinite Stream II
Same solution as "3023. Find Pattern in Infinite Stream I" but with a larger constraint: 1 <= pattern.length <= 10000 instead of 1 <= pattern.length <= 100. mask = 1 << (k - 1) is precomputed before the loop, and stream_num = (stream_num | mask) ^ mask sidesteps Python's two's complement behavior compared to & ~mask.
- Time
- O(k + n)
- Building
pattern_numis a singleO(k)pass overpattern(k = len(pattern)). - The window then reads at most
O(n)elements fromstreambefore finding the match, each processed inO(1)via the mask. - Space
- O(1)
- Only scalar bitmask variables (
pattern_num,stream_num,mask) are tracked; no structure scales withkorn.
Miscellaneous
30. Substring with Concatenation of All Words
Find all starting indices in s where a substring is the exact concatenation of all words. The window size is k = len(words) * word_len. A needed counter tracks word frequencies. The window expands by examining word-length segments and shrinks by word-length steps.
Multiple starting offsets (0 to word_len - 1) are tried to cover all possible alignments.
Expansion:
- Extract
word = s[right:right+word_len], decrement its count inneeded. Remove the entry if it reaches zero.
Logic:
- If
neededis empty, all words are matched. Appendlefttoans.
Shrinking:
- Re-add the leftmost word to
neededand advanceleftbyword_len.
- Time
- O(w * (M + n))
wis the length of each word. For each of thewstarting offsets, buildingCounter(words)costsO(M)(M= total characters across all words), and slidingleft/rightacrosss(lengthn) inw-sized steps costsO(n).- Space
- O(M + n)
counterholds entries proportional to total word lengthM, andresultcould hold up tonindices.