Bird
Raised Fist0
Interview Prepsliding-windowhardAmazonGoogleMicrosoft

Sliding Window Maximum (Monotonic Deque)

Choose your preparation mode4 modes available
▶
Steps
setup

Initialize variables

Initialize an empty deque to store indices and an empty result list to store maximums.

💡 Setting up the deque and result list is essential before processing any elements.
Line:dq = deque() # stores indices result = []
💡 The deque will hold indices, not values, to efficiently track window boundaries.
📊
Sliding Window Maximum (Monotonic Deque) - Watch the Algorithm Execute, Step by Step
Watching the algorithm step-by-step reveals how the deque structure efficiently tracks maximums without redundant comparisons, which is hard to grasp from code alone.
Step 1/20
·Active fill★Answer cell
no_op
Stack (top→bottom)
empty
pushElement[0]: 1
Stack (top→bottom)
0
↑ pushed: 0
popElement[1]: 3
Stack (top→bottom)
1
↓ popped: [0]
pushElement[2]: -1
Stack (top→bottom)
2
1
↑ pushed: 2
no_opElement[2]: -1
Stack (top→bottom)
2
1
Contributes: 3
pushElement[3]: -3
Stack (top→bottom)
3
2
1
↑ pushed: 3
no_opElement[3]: -3
Stack (top→bottom)
3
2
1
no_opElement[3]: -3
Stack (top→bottom)
3
2
1
Contributes: 3
popElement[4]: 5
Stack (top→bottom)
4
↓ popped: [3, 2, 1]
no_opElement[4]: 5
Stack (top→bottom)
4
no_opElement[4]: 5
Stack (top→bottom)
4
Contributes: 5
pushElement[5]: 3
Stack (top→bottom)
5
4
↑ pushed: 5
no_opElement[5]: 3
Stack (top→bottom)
5
4
no_opElement[5]: 3
Stack (top→bottom)
5
4
Contributes: 5
popElement[6]: 6
Stack (top→bottom)
6
↓ popped: [5, 4]
no_opElement[6]: 6
Stack (top→bottom)
6
no_opElement[6]: 6
Stack (top→bottom)
6
Contributes: 6
popElement[7]: 7
Stack (top→bottom)
7
↓ popped: [6]
no_opElement[7]: 7
Stack (top→bottom)
7
no_opElement[7]: 7
Stack (top→bottom)
7
Contributes: 7

Key Takeaways

✓ The deque maintains indices of elements in decreasing order of their values, ensuring the front is always the maximum in the current window.

This insight is hard to see from code alone because it requires understanding how popping smaller elements preserves the maximum at the front.

✓ Elements are removed from the deque when they fall out of the sliding window range, ensuring the deque only contains relevant indices.

This pruning step is crucial to avoid stale indices and is often overlooked without visualization.

✓ The algorithm efficiently finds maximums without scanning the entire window by leveraging the monotonic property of the deque.

Watching the step-by-step popping and pushing clarifies why this approach is optimal compared to naive scanning.

Practice

(1/5)
1. You are given an integer array and a fixed window size k. The task is to find the contiguous subarray of length k that has the maximum average value. Which algorithmic approach guarantees an optimal solution with linear time complexity?
easy
A. Sliding window technique maintaining a running sum of the current window
B. Brute force nested loops checking all subarrays of size k
C. Dynamic programming with memoization of subproblems
D. Greedy approach selecting the largest elements regardless of position

Solution

  1. Step 1: Understand problem constraints

    The problem requires finding the maximum average of any contiguous subarray of fixed size k, which suggests examining all windows of size k.
  2. Step 2: Identify optimal approach

    Sliding window maintains a running sum by adding the new element and removing the oldest, achieving O(n) time. Brute force is O(n*k), DP and greedy do not fit this fixed-size window problem optimally.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Sliding window updates sum in O(1) per step, total O(n) time [OK]
Hint: Sliding window updates sum in O(1) per step [OK]
Common Mistakes:
  • Thinking greedy works without considering window contiguity
  • Assuming DP is needed for fixed-size windows
2. Consider the following Python function that counts the number of contiguous subarrays where the product of all elements is less than k. What is the returned value when calling numSubarrayProductLessThanK([10, 5, 2, 6], 100)?
def numSubarrayProductLessThanK(nums, k):
    if k <= 1:
        return 0
    product = 1.0
    count = 0
    left = 0
    for right in range(len(nums)):
        product *= nums[right]
        while product >= k and left <= right:
            product /= nums[left]
            left += 1
        count += right - left + 1
    return count
easy
A. 8
B. 7
C. 9
D. 10

Solution

  1. Step 1: Trace product and window boundaries

    Iterate right pointer: - right=0: product=10 <100, count=1 - right=1: product=50 <100, count=1+2=3 - right=2: product=100 ≥100, shrink window: product/=10=10, left=1, count=3+(2-1+1)=5 - right=3: product=10*6=60 <100, count=5+(3-1+1)=8
  2. Step 2: Final count

    Total count is 8 valid subarrays.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Count matches expected output 8 [OK]
Hint: Count increments by window size each iteration [OK]
Common Mistakes:
  • Off-by-one in count increment
  • Not shrinking window correctly
3. The following code attempts to find all anagrams of p in s using a sliding window with count matching optimization. Which line contains a subtle bug that can cause incorrect results or runtime errors?
medium
A. Line missing decrement of window_count[left_index] when shrinking window
B. Line checking if window_count[index] == p_count[index] + 1 to decrement matches
C. Line incrementing window_count[index] when adding right character
D. Line appending left index to result when matches == 26

Solution

  1. Step 1: Identify window shrinking logic

    When window size exceeds p length, left character count must be decremented.
  2. Step 2: Locate missing decrement

    The code does not decrement window_count[left_index] before moving left pointer, causing incorrect counts.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Missing decrement breaks frequency tracking [OK]
Hint: Always decrement count when shrinking window [OK]
Common Mistakes:
  • Forgetting to decrement frequency on window shrink
  • Incorrect matches update logic
  • Appending wrong indices
4. What is the time complexity of the sliding window approach to find the maximum sum subarray of size k in an array of length n, and why might some candidates mistakenly think it is higher?
medium
A. O(n log k) because maintaining the window sum requires a balanced data structure.
B. O(n*k) because each window sum is recomputed from scratch for k elements.
C. O(n) because the window sum is updated in constant time for each of the n-k+1 windows.
D. O(k) because the initial sum computation dominates the runtime.

Solution

  1. Step 1: Analyze the sliding window updates

    After computing the initial sum of the first k elements (O(k)), each subsequent window sum is updated by adding one element and removing one element, both O(1) operations.
  2. Step 2: Calculate total time complexity

    There are (n-k) such updates, so total time is O(k) + O(n-k) = O(n). Candidates often mistake it as O(n*k) by assuming sum recomputation each time.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    Sliding window updates in O(1) per step -> total O(n) [OK]
Hint: Sliding window updates sum in O(1) per step -> total O(n) [OK]
Common Mistakes:
  • Assuming sum is recomputed fully for each window
  • Confusing initial sum cost with per-iteration cost
  • Thinking data structures like heaps are needed
5. Suppose the problem is modified so that characters in t can be reused unlimited times (i.e., the substring in s must contain at least one occurrence of each character in t, but counts do not matter). Which modification to the sliding window algorithm correctly solves this variant?
hard
A. Keep frequency counts and require window_count[c] >= t_count[c] for all c, same as original
B. Use brute force to check all substrings since counts no longer matter
C. Sort s and t and use two pointers to find minimal substring
D. Track only presence of characters from t in the window, increment have when a character appears at least once, decrement when it disappears

Solution

  1. Step 1: Understand problem change

    Since counts do not matter, only presence of each character is required, so frequency counts can be replaced by boolean presence tracking.
  2. Step 2: Modify sliding window logic

    Increment have when a character from t appears first time in window, decrement when it leaves. Shrink window when all characters are present.
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    Tracking presence instead of counts solves the reuse variant efficiently [OK]
Hint: Track presence, not counts, when duplicates don't matter [OK]
Common Mistakes:
  • Using original count-based logic
  • Assuming brute force is needed
  • Sorting breaks substring order
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard