Skip to content

Commit f871583

Browse files
committed
feat: add sliding window maximum using monotonic deque
1 parent 3c88735 commit f871583

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

other/sliding_window_maximum.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
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

Comments
 (0)