Maximum of Every Sliding Window of Size K
Solve this Problemnums and an integer k, return an array where each value is the maximum of the window nums[i..i+k-1], for every valid window position as the window slides from the start of the array to the end.
Recomputing the max of every window from scratch is correct but wasteful — most of a window's elements are shared with the window right before it. The fix is a deque that only ever holds candidates that could still become a future window's maximum, kept in strictly decreasing order of value. Because the front of a decreasing deque is always the biggest value currently in the window, reading the answer for each window becomes O(1), and every index is pushed and popped from the deque at most once — giving O(n) overall despite the nested-looking while loops inside the for.
Test Case 1:
Test Case 2:
Test Case 3:
Constraints
- ◆
1 ≤ nums.length ≤ 10⁵ - ◆
-10⁴ ≤ nums[i] ≤ 10⁴ - ◆
1 ≤ k ≤ nums.length
Try the Dry Run
Don't just read the solution — watch it execute, one step at a time.
| 1 | class Solution { |
| 2 | public int[] maxOfEverySlidingWindow(int[] nums, int k) { |
| 3 | Deque<Integer> deque = new ArrayDeque<>(); |
| 4 | int[] result = new int[nums.length - k + 1]; |
| 5 | for (int i = 0; i < nums.length; i++) { |
| 6 | while (!deque.isEmpty() && deque.peekFirst() <= i - k) { |
| 7 | deque.pollFirst(); |
| 8 | } |
| 9 | while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) { |
| 10 | deque.pollLast(); |
| 11 | } |
| 12 | deque.offerLast(i); |
| 13 | if (i >= k - 1) { |
| 14 | result[i - k + 1] = nums[deque.peekFirst()]; |
| 15 | } |
| 16 | } |
| 17 | return result; |
| 18 | } |
| 19 | } |
| 20 |
Start with an empty deque of indices (front is always the current window's max) and an empty result array.
Approach & Solutions
Brute Force
BruteFor every window start, scan all k elements to find the maximum and store it. Correct, but every window shares almost all of its elements with the window right before it — re-scanning from scratch every time throws that overlap away.
O(n·k)O(n-k+1)1class Solution {
2 public int[] maxOfEverySlidingWindow(int[] nums, int k) {
3 int[] result = new int[nums.length - k + 1];
4 for (int i = 0; i <= nums.length - k; i++) {
5 int max = nums[i];
6 for (int j = i; j < i + k; j++) {
7 max = Math.max(max, nums[j]);
8 }
9 result[i] = max;
10 }
11 return result;
12 }
13}Optimal — Monotonic Deque
OptimalKeep a deque of indices whose values are in strictly decreasing order, so the front is always the max of the current window. At each index: drop any front index that has fallen out of the window, drop any back index whose value is smaller than the one just arrived (it can never be a future max), then push the new index. Once the window is full, the front is the answer — no re-scanning.
O(n)O(k)1class Solution {
2 public int[] maxOfEverySlidingWindow(int[] nums, int k) {
3 Deque<Integer> deque = new ArrayDeque<>();
4 int[] result = new int[nums.length - k + 1];
5 for (int i = 0; i < nums.length; i++) {
6 while (!deque.isEmpty() && deque.peekFirst() <= i - k) {
7 deque.pollFirst();
8 }
9 while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) {
10 deque.pollLast();
11 }
12 deque.offerLast(i);
13 if (i >= k - 1) {
14 result[i - k + 1] = nums[deque.peekFirst()];
15 }
16 }
17 return result;
18 }
19}