You are given an array of integers nums
, there is a sliding window of size k
which is moving from the very left of the array to the very right. You can only see the k
numbers in the window. Each time the sliding window moves right by one position.
Return the max sliding window.
Example 1:
Input: nums = [1,3,-1,-3,5,3,6,7], k = 3 Output: [3,3,5,5,6,7] Explanation: Window position Max --------------- ----- [1 3 -1] -3 5 3 6 7 3 1 [3 -1 -3] 5 3 6 7 3 1 3 [-1 -3 5] 3 6 7 5 1 3 -1 [-3 5 3] 6 7 5 1 3 -1 -3 [5 3 6] 7 6 1 3 -1 -3 5 [3 6 7] 7
Example 2:
Input: nums = [1], k = 1 Output: [1]
Constraints:
1 <= nums.length <= 105
-104 <= nums[i] <= 104
1 <= k <= nums.length
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
Imagine you're looking through a long line of numbers, and you want to find the biggest number within each chunk of a certain size. The brute force method simply checks every possible chunk, one by one. It's like sliding a window along the numbers and, for each window position, exhaustively scanning all the numbers within that window.
Here's how the algorithm would work step-by-step:
def sliding_window_maximum_brute_force(numbers, window_size):
maximums = []
number_of_elements = len(numbers)
# Iterate through the array, considering each possible starting position for the window
for i in range(number_of_elements - window_size + 1):
window_maximum = numbers[i]
# Iterate through the current window to find the maximum element
for j in range(1, window_size):
if numbers[i + j] > window_maximum:
window_maximum = numbers[i + j]
# Append the maximum value of the current window to the result
maximums.append(window_maximum)
return maximums
The best way to find the maximum value within a moving window is to avoid recalculating everything each time the window shifts. We'll use a special container to keep track of potentially maximum values within the current window, smartly updating it as the window slides.
Here's how the algorithm would work step-by-step:
from collections import deque
def sliding_window_maximum(numbers, window_size):
if not numbers:
return []
result = []
deque_of_indices = deque()
for index in range(len(numbers)):
# Remove indices that are out of the current window
while deque_of_indices and deque_of_indices[0] <= index - window_size:
deque_of_indices.popleft()
# Remove indices of smaller elements from the back
# The queue maintains a decreasing order.
while deque_of_indices and numbers[deque_of_indices[-1]] < numbers[index]:
deque_of_indices.pop()
deque_of_indices.append(index)
# Add the maximum element to the result if the window has formed.
if index >= window_size - 1:
# The leftmost element is always the maximum
result.append(numbers[deque_of_indices[0]])
return result
Case | How to Handle |
---|---|
Empty input array | Return an empty array since there are no elements to process. |
k is 0 | Return an empty array as a window of size 0 is invalid. |
k is 1 | The maximum of each window is simply the element itself, return the original array. |
k is greater than the array length | Return an array containing only the maximum element of the entire array. |
Array contains all identical elements | The maximum within each window will be the same element, which the algorithm correctly handles. |
Array contains negative numbers and zeros | The algorithm should correctly identify the maximum even with negative numbers and zeros. |
Large array size with small k | Using a deque optimization provides better time complexity compared to brute force approach, scaling the processing time effectively. |
Array sorted in descending order | The first element will always be the maximum for each window, which the algorithm handles correctly. |