1+ from collections import deque
2+ from typing import Deque , List
3+
4+
5+ def sliding_window_maximum (numbers : List [int ], window_size : int ) -> List [int ]:
6+ """
7+ Return a list containing the maximum of each sliding window of size window_size.
8+
9+ This implementation uses a monotonic deque to achieve O(n) time complexity.
10+
11+ Args:
12+ numbers: List of integers representing the input array.
13+ window_size: Size of the sliding window (must be positive).
14+
15+ Returns:
16+ List of maximum values for each valid window.
17+
18+ Raises:
19+ ValueError: If window_size is not a positive integer.
20+
21+ Time Complexity: O(n) - each element is added and removed at most once
22+ Space Complexity: O(k) - deque stores at most window_size indices
23+
24+ Examples:
25+ >>> sliding_window_maximum([1, 3, -1, -3, 5, 3, 6, 7], 3)
26+ [3, 3, 5, 5, 6, 7]
27+ >>> sliding_window_maximum([9, 11], 2)
28+ [11]
29+ >>> sliding_window_maximum([], 3)
30+ []
31+ >>> sliding_window_maximum([4, 2, 12, 3], 1)
32+ [4, 2, 12, 3]
33+ >>> sliding_window_maximum([1], 1)
34+ [1]
35+ """
36+ if window_size <= 0 :
37+ raise ValueError ("Window size must be a positive integer" )
38+ if not numbers :
39+ return []
40+
41+ result : List [int ] = []
42+ index_deque : Deque [int ] = deque ()
43+
44+ for current_index , current_value in enumerate (numbers ):
45+ # Remove the element which is out of this window
46+ if index_deque and index_deque [0 ] == current_index - window_size :
47+ index_deque .popleft ()
48+
49+ # Remove useless elements (smaller than current) from back
50+ while index_deque and numbers [index_deque [- 1 ]] < current_value :
51+ index_deque .pop ()
52+
53+ index_deque .append (current_index )
54+
55+ # Start adding to result once we have a full window
56+ if current_index >= window_size - 1 :
57+ result .append (numbers [index_deque [0 ]])
58+
59+ return result
0 commit comments