Problem
Given an array of size n and an integer k, we need to find the maximum element for each contiguous subarray of size k.
Sliding window using Deque
We’ll discuss a solution using the sliding window approach, which allows us to solve the problem with a time complexity of O(n). We’ll be using a Double-ended queue (Deque) to solve this problem.
The sliding window approach involves maintaining a window of elements as we traverse the array. In this problem, we’ll use a deque (double-ended queue) to efficiently find the maximum within the current window. The deque will store indices of array elements in a way that ensures the maximum element is always at the front.
Sliding window approach is also discussed in these posts:
- Find maximum sum of contiguous subarray of size k
- Find number of subarrays with given sum (positive numbers)
Example
Input: array (nums) = [1, 3, -1, -3, 5, 3, 6, 7], k = 3 Output: [3, 3, 5, 5, 6, 7]
Approach
- Initialise an empty deque using the first k elements of the array.
- Iterate through the array from index kto the end(n-1).- Remove elements from the front of the deque that are outside the current window.
- Next, remove the elements from the back of the deque that are lesser than the current element
- The front of the deque now contains the maximum element index for the current window. Add the current index to the deque.
- Add the maximum element to the result for the current window.
 
- Return the result array (ans) containing maximum elements for each window of size k.
Pseudocode
1. Create an empty deque (dq) to store indices of the array.
2. Process first k elements of the array to initialise deque (initialise_deque).
3. for i = k to n-1 (iterate through array):
4.   while dq.front() <= i-k:
       dq.pop_front()
5.   while nums[i] > nums[dq.back]:
       dq.pop_back()
5.   dq.push_back(i) 
initialise_deque (dq, nums):
  for i = 0 to k-1:
    (remove elements from the back of the deque until the current element is greater than the queue's back element)
    while nums[i] > nums[dq.back]:
      dq.pop_back()
    dq.push_back(i)
Code Implementation
//
//  main.cpp
//  Maximum of all Subarrays of Size k
//
//  Created by Himanshu on 10/01/22.
//
#include <iostream>
#include <vector>
#include <deque>
using namespace std;
vector<int> maxSlidingWindow(const vector<int>& nums, int k) {
    vector<int> result;
    deque<int> dq;
    // Process the first k elements
    for (int i = 0; i < k; i++) {
        
        while (!dq.empty() && nums[i] > nums[dq.back()]){
            dq.pop_back();
        }
        
        dq.push_back(i);
    }
    // Iterate through the array from index k to the end
    for (int i = k; i < nums.size(); i++) {
        
        // Add the maximum element of the curent window
        // to the result
        result.push_back(nums[dq.front()]);
        // Remove elements from the front of the deque 
        // that are outside the current window
        while (!dq.empty() && dq.front() <= i - k) {
            dq.pop_front();
        }
        // Remove elements from the back until the current element 
        // is greater than the element at the back
        while (!dq.empty() && nums[i] > nums[dq.back()]) {
            dq.pop_back();
        }
        // Add the current index to the deque
        dq.push_back(i);
    }
    // Add the maximum element for the last window
    result.push_back(nums[dq.front()]);
    
    return result;
}
int main() {
    vector<int> nums = {1, 3, 2, -3, 5, -2, 6, 7};
    int k = 3;
    vector<int> result = maxSlidingWindow(nums, k);
    // Print the result
    for (int num : result) {
        cout << num << " ";
    }
    return 0;
}
Output
3 3 5 5 6 7
Time complexity: O(n)
Auxiliary space: O(k)