Taro Logo

Sliding Window Maximum

Hard
Google logo
Google
Topics:
ArraysSliding Windows

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 <= 10^5
  • -10^4 <= nums[i] <= 10^4
  • 1 <= k <= nums.length

Can you implement a function to efficiently find the maximum element in each sliding window?

Solution


Brute Force Solution

A naive approach to solve this problem would be to iterate through the array using a sliding window of size k. For each window, find the maximum element within that window and add it to the result.

def max_sliding_window_brute_force(nums, k):
    if not nums:
        return []
    
    result = []
    for i in range(len(nums) - k + 1):
        window = nums[i:i+k]
        result.append(max(window))
        
    return result

Time Complexity

The time complexity of this approach is O(n*k), where n is the length of the input array nums and k is the size of the sliding window. This is because for each of the n-k+1 windows, we iterate through k elements to find the maximum.

Space Complexity

The space complexity is O(n-k+1) or O(n) in the worst case, to store the result. It can be considered O(1) if we don't count the space for the output array.

Optimal Solution (Using Deque)

A more efficient solution utilizes a deque (double-ended queue) to keep track of the indices of the potentially maximum elements in the current window. The deque stores indices in decreasing order of their corresponding values in the array.

from collections import deque

def max_sliding_window(nums, k):
    if not nums:
        return []
    
    deque_ = deque()
    result = []
    
    for i in range(len(nums)):
        # Remove elements out of the window
        while deque_ and deque_[0] <= i - k:
            deque_.popleft()
        
        # Remove smaller elements in deque than current element
        while deque_ and nums[deque_[-1]] <= nums[i]:
            deque_.pop()
        
        deque_.append(i)
        
        # Add max to result
        if i >= k - 1:
            result.append(nums[deque_[0]])
            
    return result

Explanation

  1. Initialization: Initialize a deque and a result list.
  2. Iteration: Iterate through the array nums.
  3. Remove Out-of-Window Elements: Remove indices from the front of the deque that are no longer in the current window.
  4. Maintain Decreasing Order: Remove indices from the back of the deque whose corresponding values are smaller than the current element. This ensures the deque always contains indices of elements in decreasing order.
  5. Add Current Element: Append the current element's index to the back of the deque.
  6. Add Max to Result: Once the window is full (i.e., the index is greater than or equal to k-1), append the element at the front of the deque (which is the maximum element in the current window) to the result.

Time Complexity

The time complexity of this optimized solution is O(n), where n is the length of the input array. Each element is processed at most twice (once when it's added to the deque and once when it's removed).

Space Complexity

The space complexity is O(k), where k is the size of the sliding window. This is because the deque can contain at most k elements.

Edge Cases

  • Empty Input: If the input array is empty, return an empty list.
  • Window Size 1: If the window size is 1, return the original array.
  • Window Size Equal to Array Length: If the window size is equal to the array length, return a list containing the maximum element of the array.