Sliding Window Maximum Using Deque in DSA Python - Time & Space Complexity
We want to understand how the time needed to find the maximum in each sliding window changes as the input size grows.
Specifically, how fast can we find maximums when moving a window over an array?
Analyze the time complexity of the following code snippet.
from collections import deque
def max_sliding_window(nums, k):
dq = deque()
result = []
for i, num in enumerate(nums):
while dq and nums[dq[-1]] < num:
dq.pop()
dq.append(i)
if dq[0] == i - k + 1:
dq.popleft()
if i >= k - 1:
result.append(nums[dq[0]])
return result
This code finds the maximum value in every window of size k as it slides over the list nums.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: A single loop over all elements in nums.
- How many times: Each element is added and removed from the deque at most once.
As the input size n grows, each element is processed a limited number of times, so the total work grows roughly in direct proportion to n.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 20 operations (each element added and removed once) |
| 100 | About 200 operations |
| 1000 | About 2000 operations |
Pattern observation: The operations grow linearly with input size.
Time Complexity: O(n)
This means the time to find all sliding window maximums grows directly with the size of the input list.
[X] Wrong: "Because there is a nested while loop inside the for loop, the time complexity must be O(n²)."
[OK] Correct: Each element is pushed and popped from the deque only once, so the total number of operations inside the while loop across the entire run is at most n, not n times n.
Understanding this efficient approach shows you can optimize problems by cleverly managing data, a skill highly valued in real-world coding challenges.
What if we replaced the deque with a simple list and searched for the maximum in each window? How would the time complexity change?
Practice
Solution
Step 1: Understand the role of deque
A deque stores indices of elements in the current window, maintaining order to quickly find the max.Step 2: Why not other options?
Sorting or reversing is not done; sum is unrelated to max. Deque helps track max efficiently.Final Answer:
To store indices of elements in a way that helps find the maximum efficiently -> Option DQuick Check:
Deque stores indices for max tracking [OK]
- Thinking deque stores actual values instead of indices
- Assuming deque sorts the array
- Confusing deque with sum calculation
Solution
Step 1: Import deque correctly
Deque must be imported from collections module before use.Step 2: Initialize empty deque
Using dq = deque() after import is correct syntax; dq = deque([]) also works but less common.Final Answer:
from collections import deque; dq = deque() -> Option AQuick Check:
Import then dq = deque() [OK]
- Using list [] instead of deque
- Not importing deque before use
- Using collections.deque() without import
from collections import deque
def max_sliding_window(nums, k):
dq = deque()
result = []
for i in range(len(nums)):
while dq and dq[0] <= i - k:
dq.popleft()
while dq and nums[dq[-1]] < nums[i]:
dq.pop()
dq.append(i)
if i >= k - 1:
result.append(nums[dq[0]])
return result
print(max_sliding_window([1,3,-1,-3,5,3,6,7], 3))Solution
Step 1: Understand sliding window max logic
For each window of size 3, the code finds max by maintaining indices in dq.Step 2: Trace output for input
Windows and max: [1,3,-1] -> 3, [3,-1,-3] -> 3, [-1,-3,5] -> 5, [-3,5,3] -> 5, [5,3,6] -> 6, [3,6,7] -> 7Final Answer:
[3, 3, 5, 5, 6, 7] -> Option AQuick Check:
Sliding window max = [3,3,5,5,6,7] [OK]
- Appending values instead of indices to deque
- Not removing indices out of window
- Confusing window size with output length
from collections import deque
def max_sliding_window(nums, k):
dq = deque()
result = []
for i in range(len(nums)):
while dq and nums[dq[-1]] <= nums[i]:
dq.pop()
dq.append(i)
if dq[0] == i - k:
dq.popleft()
if i >= k - 1:
result.append(nums[dq[0]])
return result
print(max_sliding_window([1,3,-1,-3,5,3,6,7], 3))Solution
Step 1: Check condition for removing old indices
Indices outside the window must be removed when dq[0] <= i - k (equivalent to dq[0] < i - k + 1).Step 2: Analyze given condition
Given condition dq[0] == i - k removes only if exactly equal, missing older indices or multiples; must use while loop too.Final Answer:
The condition to remove old indices should be dq[0] <= i - k -> Option BQuick Check:
Remove indices outside window with dq[0] <= i - k [OK]
- Using equality instead of less than for removal
- Removing indices too late causing wrong max
- Not removing old indices at all
nums = [4, 2, 12, 3, 8, 7, 9] and window size k = 4, what is the output of the sliding window maximum using deque approach?Solution
Step 1: Identify windows and their max values
Windows of size 4: [4,2,12,3] max=12, [2,12,3,8] max=12, [12,3,8,7] max=12, [3,8,7,9] max=9.Step 2: Verify max values carefully
Third window max is 12, but 12 is at index 2, window covers indices 2-5: 12,3,8,7 max=12. Fourth window max is 9.Final Answer:
[12, 12, 12, 9] -> Option CQuick Check:
Sliding window max for k=4 = [12,12,12,9] [OK]
- Mixing up window boundaries
- Choosing wrong max by ignoring window size
- Confusing values with indices
Ready to prove it?
Pass the test and this pattern moves unknown
