Patterns / Intermediate
Sliding Window Maximum Visualizer
A deque holds indexes whose values only go down from front to back. A new value pops every smaller value off the back, since those can never be a maximum again. The front is the window maximum; drop it once it slides out.
Start the Sliding Window Maximum simulation → Step forward and back, change the input, follow the code line by line in Java, Python, C++, C or JavaScript. Free, no sign-up.
Time and space complexity
| Best time | O(n) |
|---|---|
| Average time | O(n) |
| Worst time | O(n) |
| Extra space | O(k) |
Worked example, step by step
The same steps the simulator shows, on a small input.
- Window size k = 3. The deque starts empty.
[1, 3, -1, -3, 5, 3, 6, 7] - Push 1 on the back. The deque still falls from front to back.
- 1 ≤ 3, so 1 can never be a maximum again. Pop it from the back.
- Push 3 on the back. The deque still falls from front to back.
- Push -1 on the back. The deque still falls from front to back.
- Window [0..2] is full. Its maximum is the front: 3.
- Push -3 on the back. The deque still falls from front to back.
- Window [1..3] is full. Its maximum is the front: 3.
- Index 1 (3) has slid out of the window. Drop it from the front.
- -3 ≤ 5, so -3 can never be a maximum again. Pop it from the back.
- -1 ≤ 5, so -1 can never be a maximum again. Pop it from the back.
- Push 5 on the back. The deque still falls from front to back.
- Window [2..4] is full. Its maximum is the front: 5.
- Push 3 on the back. The deque still falls from front to back.
- Window [3..5] is full. Its maximum is the front: 5.
- 3 ≤ 6, so 3 can never be a maximum again. Pop it from the back.
- 5 ≤ 6, so 5 can never be a maximum again. Pop it from the back.
- Push 6 on the back. The deque still falls from front to back.
- Window [4..6] is full. Its maximum is the front: 6.
- 6 ≤ 7, so 6 can never be a maximum again. Pop it from the back.
- Push 7 on the back. The deque still falls from front to back.
- Window [5..7] is full. Its maximum is the front: 7.
- Done: 3, 3, 5, 5, 6, 7.
Sliding window maximum in Java, Python, C++, C and JavaScript
int[] maxSlidingWindow(int[] a, int k) {
Deque<Integer> dq = new ArrayDeque<>();
int[] out = new int[a.length - k + 1];
for (int i = 0; i < a.length; i++) {
if (!dq.isEmpty() && dq.peekFirst() <= i - k) dq.pollFirst();
while (!dq.isEmpty() && a[dq.peekLast()] <= a[i]) dq.pollLast();
dq.offerLast(i);
if (i >= k - 1) out[i - k + 1] = a[dq.peekFirst()];
}
return out;
}
from collections import deque
def max_sliding_window(a, k):
dq = deque()
out = []
for i in range(len(a)):
if dq and dq[0] <= i - k:
dq.popleft()
while dq and a[dq[-1]] <= a[i]:
dq.pop()
dq.append(i)
if i >= k - 1:
out.append(a[dq[0]])
return out
vector<int> maxSlidingWindow(const vector<int>& a, int k) {
deque<int> dq;
vector<int> out;
for (int i = 0; i < (int)a.size(); i++) {
if (!dq.empty() && dq.front() <= i - k) dq.pop_front();
while (!dq.empty() && a[dq.back()] <= a[i]) dq.pop_back();
dq.push_back(i);
if (i >= k - 1) out.push_back(a[dq.front()]);
}
return out;
}
#include <stdlib.h>
void maxSlidingWindow(int a[], int n, int k, int out[]) {
int *dq = malloc(n * sizeof(int)), head = 0, tail = 0;
for (int i = 0; i < n; i++) {
if (head < tail && dq[head] <= i - k) head++;
while (head < tail && a[dq[tail - 1]] <= a[i]) tail--;
dq[tail++] = i;
if (i >= k - 1) out[i - k + 1] = a[dq[head]];
}
free(dq);
}
function maxSlidingWindow(a, k) {
const dq = [];
const out = [];
for (let i = 0; i < a.length; i++) {
if (dq.length > 0 && dq[0] <= i - k) dq.shift();
while (dq.length > 0 && a[dq[dq.length - 1]] <= a[i]) dq.pop();
dq.push(i);
if (i >= k - 1) out.push(a[dq[0]]);
}
return out;
}In an interview
LeetCode 239, Sliding Window Maximum: the largest value in every window of size k.
Store indexes, not values, so you can tell when the front has left the window. Each index enters and leaves the deque once, so the total work is O(n).