Sliding Window Maximum Using Deque in DSA Go - Time & Space Complexity
We want to understand how the time needed to find the maximum in each sliding window changes as the input grows.
How does the algorithm handle many numbers efficiently when the window moves?
Analyze the time complexity of the following code snippet.
func maxSlidingWindow(nums []int, k int) []int {
var result []int
var deque []int // stores indices
for i := 0; i < len(nums); i++ {
if len(deque) > 0 && deque[0] == i-k {
deque = deque[1:] // remove left if out of window
}
for len(deque) > 0 && nums[deque[len(deque)-1]] < nums[i] {
deque = deque[:len(deque)-1] // remove smaller from right
}
deque = append(deque, i)
if i >= k-1 {
result = append(result, nums[deque[0]])
}
}
return result
}
This code finds the maximum value in every window of size k as it slides over the array.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: One main loop over all elements of the array.
- How many times: Exactly once for each element (n times).
- Inside the loop, elements are added and removed from the deque at most once each.
- The inner while loop removes smaller elements but each element is removed only once in total.
As the input size grows, each element is processed a limited number of times.
| 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 number of operations grows roughly in a straight line with input size.
Time Complexity: O(n)
This means the time to find all sliding window maximums grows directly in proportion to the number of elements.
[X] Wrong: "Because there is a nested loop, the time complexity must be O(n²)."
[OK] Correct: The inner loop removes elements only once per element overall, so total work is still linear, not quadratic.
Understanding this efficient approach shows you can optimize problems by clever data structures, a skill highly valued in real-world coding.
"What if we used a simple array instead of a deque to track maximums? How would the time complexity change?"
Practice
Solution
Step 1: Understand the role of deque
The deque stores indices of elements in the current window, maintaining them in decreasing order of their values to quickly find the maximum.Step 2: Why not other options?
Options B, C, and D do not help in efficiently finding the maximum in each sliding window.Final Answer:
To keep track of indices of elements in the current window in decreasing order of their values -> Option AQuick Check:
Deque stores indices in decreasing order for max [OK]
- Using deque to store values instead of indices
- Sorting the entire array instead of using deque
- Not maintaining decreasing order in deque
Solution
Step 1: Check initialization methods
deque := []int{} creates an empty slice which can be used as a deque.Step 2: Why others are incorrect
make([]int, 5) creates a slice with length 5 filled with zeros, not empty. nil is not initialized. new([]int) returns pointer to nil slice, not usable directly.Final Answer:
deque := []int{} -> Option CQuick Check:
Empty slice initialization = deque := []int{} [OK]
- Using make with length > 0 creates non-empty slice
- Using nil slice without initialization
- Using new([]int) returns pointer, not slice
[1,3,-1,-3,5,3,6,7] with window size 3?Solution
Step 1: Slide window and find max
Windows and max values: [1,3,-1] -> 3, [3,-1,-3] -> 3, [-1,-3,5] -> 5, [-3,5,3] -> 5, [5,3,6] -> 6, [3,6,7] -> 7Step 2: Collect max values in order
The output array is [3, 3, 5, 5, 6, 7].Final Answer:
[3, 3, 5, 5, 6, 7] -> Option AQuick Check:
Sliding window max = [3, 3, 5, 5, 6, 7] [OK]
- Confusing window size or indices
- Taking min instead of max
- Off-by-one errors in window sliding
for i := 0; i < len(nums); i++ {
if len(deque) > 0 && deque[0] <= i-k {
deque = deque[1:]
}
for len(deque) > 0 && nums[deque[len(deque)-1]] < nums[i] {
deque = deque[:len(deque)-1]
}
deque = append(deque, i)
if i >= k-1 {
result = append(result, nums[deque[0]])
}
}Solution
Step 1: Check deque initialization
The code uses deque but does not show initialization. Without initializing deque as an empty slice, appending will cause runtime error.Step 2: Other parts are correct
Conditions and loop indices are standard for sliding window maximum. Append to result after deque update is correct.Final Answer:
Deque is not initialized before the loop -> Option BQuick Check:
Deque must be initialized before use [OK]
- Forgetting to initialize deque slice
- Incorrect window boundary condition
- Appending result too early
nums = [4, 2, 12, 3, 8, 7, 9] and window size 4, what is the sliding window maximum output using deque? Also, explain why deque helps achieve O(n) time complexity.Solution
Step 1: Calculate sliding window max values
Windows and max: [4,2,12,3] -> 12, [2,12,3,8] -> 12, [12,3,8,7] -> 12, [3,8,7,9] -> 9Step 2: Explain deque efficiency
Deque stores indices of elements in decreasing order. Each element is added and removed at most once, so total operations are O(n), avoiding repeated scanning.Final Answer:
[12, 12, 12, 9] -> Option DQuick Check:
Sliding window max = [12, 12, 12, 9], deque gives O(n) [OK]
- Calculating max incorrectly for windows
- Not understanding deque's O(n) benefit
- Confusing window size or indices
Ready to prove it?
Pass the test and this pattern moves unknown
