Skip to content
Related Articles

Related Articles

Sliding Window Maximum (Maximum of all subarrays of size K)

Improve Article
Save Article
  • Difficulty Level : Hard
  • Last Updated : 18 Oct, 2022
Improve Article
Save Article

Given an array and an integer K, find the maximum for each and every contiguous subarray of size K.

Examples : 

Input: arr[] = {1, 2, 3, 1, 4, 5, 2, 3, 6}, K = 3 
Output: 3 3 4 5 5 5 6
Explanation: Maximum of 1, 2, 3 is 3
                       Maximum of 2, 3, 1 is 3
                       Maximum of 3, 1, 4 is 4
                       Maximum of 1, 4, 5 is 5
                       Maximum of 4, 5, 2 is 5 
                       Maximum of 5, 2, 3 is 5
                       Maximum of 2, 3, 6 is 6

Input: arr[] = {8, 5, 10, 7, 9, 4, 15, 12, 90, 13}, K = 4 
Output: 10 10 10 15 15 90 90
Explanation: Maximum of first 4 elements is 10, similarly for next 4 
                       elements (i.e from index 1 to 4) is 10, So the sequence 
                       generated is 10 10 10 15 15 90 90

Complete Interview Preparation - GFG

Naive Approach: To solve the problem using this approach follow the below idea:

The idea is very basic run a nested loop, the outer loop which will mark the starting point of the subarray of length K, the inner loop will run from the starting index to index+K, and print the maximum element among these K elements. 

Follow the given steps to solve the problem:

  • Create a nested loop, the outer loop from starting index to N – Kth elements. The inner loop will run for K iterations.
  • Create a variable to store the maximum of K elements traversed by the inner loop.
  • Find the maximum of K elements traversed by the inner loop.
  • Print the maximum element in every iteration of the outer loop

Below is the implementation of the above approach:

C




// C program for the above approach
#include <stdio.h>
 
void printKMax(int arr[], int N, int K)
{
    int j, max;
 
    for (int i = 0; i <= N - K; i++) {
        max = arr[i];
 
        for (j = 1; j < K; j++) {
            if (arr[i + j] > max)
                max = arr[i + j];
        }
        printf("%d ", max);
    }
}
 
// Driver's Code
int main()
{
    int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    int N = sizeof(arr) / sizeof(arr[0]);
    int K = 3;
   
      // Function call
    printKMax(arr, N, K);
    return 0;
}

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Method to find the maximum for each
// and every contiguous subarray of size K.
void printKMax(int arr[], int N, int K)
{
    int j, max;
 
    for (int i = 0; i <= N - K; i++) {
        max = arr[i];
 
        for (j = 1; j < K; j++) {
            if (arr[i + j] > max)
                max = arr[i + j];
        }
        cout << max << " ";
    }
}
 
// Driver's code
int main()
{
    int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    int N = sizeof(arr) / sizeof(arr[0]);
    int K = 3;
   
      // Function call
    printKMax(arr, N, K);
    return 0;
}
 
// This code is contributed by rathbhupendra

Java




// Java program for the above approach
 
public class GFG {
   
    // Method to find the maximum for
    // each and every contiguous
    // subarray of size K.
    static void printKMax(int arr[], int N, int K)
    {
        int j, max;
 
        for (int i = 0; i <= N - K; i++) {
 
            max = arr[i];
 
            for (j = 1; j < K; j++) {
                if (arr[i + j] > max)
                    max = arr[i + j];
            }
            System.out.print(max + " ");
        }
    }
 
    // Driver's code
    public static void main(String args[])
    {
        int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        int K = 3;
       
          // Function call
        printKMax(arr, arr.length, K);
    }
}
 
// This code is contributed by Sumit Ghosh

Python3




# Python3 program for the above approach
 
# Method to find the maximum for each
# and every contiguous subarray
# of size K
 
def printMax(arr, N, K):
    max = 0
 
    for i in range(N - K + 1):
        max = arr[i]
        for j in range(1, K):
            if arr[i + j] > max:
                max = arr[i + j]
        print(str(max) + " ", end="")
 
 
# Driver's code
if __name__ == "__main__":
    arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    N = len(arr)
    K = 3
     
    # Function call
    printMax(arr, N, K)
 
# This code is contributed by Shiv Shankar

C#




// C# program for the above approach
 
using System;
 
class GFG {
   
    // Method to find the maximum for
    // each and every contiguous subarray
    // of size k.
    static void printKMax(int[] arr, int N, int K)
    {
        int j, max;
 
        for (int i = 0; i <= N - K; i++) {
 
            max = arr[i];
 
            for (j = 1; j < K; j++) {
                if (arr[i + j] > max)
                    max = arr[i + j];
            }
            Console.Write(max + " ");
        }
    }
 
    // Driver's code
    public static void Main()
    {
        int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        int K = 3;
        printKMax(arr, arr.Length, K);
    }
}
 
// This Code is Contributed by Sam007

PHP




<?php
// php program for the above approach
 
function printKMax($arr, $N, $K)
{
    $j; $max;
 
    for ($i = 0; $i <= $N - $K; $i++)
    {
        $max = $arr[$i];
 
        for ($j = 1; $j < $K; $j++)
        {
            if ($arr[$i + $j] > $max)
            $max = $arr[$i + $j];
        }
        printf("%d ", $max);
    }
}
 
// Driver's Code
$arr = array(1, 2, 3, 4, 5,
             6, 7, 8, 9, 10);
$N = count($arr);
$K = 3;
 
// Function call
printKMax($arr, $N, $K);
 
// This Code is Contributed by anuj_67.
?>

Javascript




// JavaScript Program to find the maximum for
// each and every contiguous subarray of size k.
 
// Method to find the maximum for each
// and every contiguous subarray of size k.
function printKMax(arr,n,k)
{
    let j, max;
 
    for (let i = 0; i <= n - k; i++)
    {
        max = arr[i];
 
        for (j = 1; j < k; j++)
        {
            if (arr[i + j] > max)
                max = arr[i + j];
        }
         document.write( max + " ");
    }
}
 
// Driver code
 
    let arr = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
    let n =arr.length;
    let k = 3;
    printKMax(arr, n, k);
 
// This code contributed by gauravrajput1

Output

3 4 5 6 7 8 9 10 

Time Complexity: O(N * K), The outer loop runs N-K+1 times and the inner loop runs K times for every iteration of the outer loop. So time complexity is O((n-k+1)*k) which can also be written as O(N * K)
Auxiliary Space: O(1)

Maximum of all subarrays of size K using Deque: 

Create a Deque, Qi of capacity K, that stores only useful elements of current window of K elements. An element is useful if it is in current window and is greater than all other elements on right side of it in current window. Process all array elements one by one and maintain Qi to contain useful elements of current window and these useful elements are maintained in sorted order. The element at front of the Qi is the largest and element at rear/back of Qi is the smallest of current window.

Below is the dry run of the above approach: 

Follow the given steps to solve the problem:

  • Create a deque to store K elements.
  • Run a loop and insert the first K elements in the deque. Before inserting the element, check if the element at the back of the queue is smaller than the current element, if it is so remove the element from the back of the deque until all elements left in the deque are greater than the current element. Then insert the current element, at the back of the deque.
  • Now, run a loop from K to the end of the array.
  • Print the front element of the deque.
  • Remove the element from the front of the queue if they are out of the current window.
  • Insert the next element in the deque. Before inserting the element, check if the element at the back of the queue is smaller than the current element, if it is so remove the element from the back of the deque until all elements left in the deque are greater than the current element. Then insert the current element, at the back of the deque.
  • Print the maximum element of the last window.

Below is the implementation of the above approach:

C++




// CPP program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// A Dequeue (Double ended queue) based
// method for printing maximum element of
// all subarrays of size k
void printKMax(int arr[], int N, int K)
{
 
    // Create a Double Ended Queue,
    // Qi that will store indexes
    // of array elements
    // The queue will store indexes
    // of useful elements in every
    // window and it will
    // maintain decreasing order of
    // values from front to rear in Qi, i.e.,
    // arr[Qi.front[]] to arr[Qi.rear()]
    // are sorted in decreasing order
    std::deque<int> Qi(K);
 
    /* Process first k (or first window)
     elements of array */
    int i;
    for (i = 0; i < K; ++i) {
 
        // For every element, the previous
        // smaller elements are useless so
        // remove them from Qi
        while ((!Qi.empty()) && arr[i] >= arr[Qi.back()])
 
            // Remove from rear
            Qi.pop_back();
 
        // Add new element at rear of queue
        Qi.push_back(i);
    }
 
    // Process rest of the elements,
    // i.e., from arr[k] to arr[n-1]
    for (; i < N; ++i) {
 
        // The element at the front of
        // the queue is the largest element of
        // previous window, so print it
        cout << arr[Qi.front()] << " ";
 
        // Remove the elements which
        // are out of this window
        while ((!Qi.empty()) && Qi.front() <= i - K)
 
            // Remove from front of queue
            Qi.pop_front();
 
        // Remove all elements
        // smaller than the currently
        // being added element (remove
        // useless elements)
        while ((!Qi.empty()) && arr[i] >= arr[Qi.back()])
            Qi.pop_back();
 
        // Add current element at the rear of Qi
        Qi.push_back(i);
    }
 
    // Print the maximum element
    // of last window
    cout << arr[Qi.front()];
}
 
// Driver's code
int main()
{
    int arr[] = { 12, 1, 78, 90, 57, 89, 56 };
    int N = sizeof(arr) / sizeof(arr[0]);
    int K = 3;
 
    // Function call
    printKMax(arr, N, K);
    return 0;
}

Java




// Java Program to find the maximum for
// each and every contiguous subarray of size K.
import java.util.Deque;
import java.util.LinkedList;
 
public class SlidingWindow {
 
    // A Dequeue (Double ended queue)
    // based method for printing
    // maximum element of
    // all subarrays of size K
    static void printMax(int arr[], int N, int K)
    {
 
        // Create a Double Ended Queue, Qi
        // that will store indexes of array elements
        // The queue will store indexes of
        // useful elements in every window and it will
        // maintain decreasing order of values
        // from front to rear in Qi, i.e.,
        // arr[Qi.front[]] to arr[Qi.rear()]
        // are sorted in decreasing order
        Deque<Integer> Qi = new LinkedList<Integer>();
 
        /* Process first k (or first window)
        elements of array */
        int i;
        for (i = 0; i < K; ++i) {
 
            // For every element, the previous
            // smaller elements are useless so
            // remove them from Qi
            while (!Qi.isEmpty()
                   && arr[i] >= arr[Qi.peekLast()])
 
                // Remove from rear
                Qi.removeLast();
 
            // Add new element at rear of queue
            Qi.addLast(i);
        }
 
        // Process rest of the elements,
        // i.e., from arr[k] to arr[n-1]
        for (; i < N; ++i) {
 
            // The element at the front of the
            // queue is the largest element of
            // previous window, so print it
            System.out.print(arr[Qi.peek()] + " ");
 
            // Remove the elements which
            // are out of this window
            while ((!Qi.isEmpty()) && Qi.peek() <= i - K)
                Qi.removeFirst();
 
            // Remove all elements smaller
            // than the currently
            // being added element (remove
            // useless elements)
            while ((!Qi.isEmpty())
                   && arr[i] >= arr[Qi.peekLast()])
                Qi.removeLast();
 
            // Add current element at the rear of Qi
            Qi.addLast(i);
        }
 
        // Print the maximum element of last window
        System.out.print(arr[Qi.peek()]);
    }
 
    // Driver's code
    public static void main(String[] args)
    {
        int arr[] = { 12, 1, 78, 90, 57, 89, 56 };
        int K = 3;
       
          // Function call
        printMax(arr, arr.length, K);
    }
}
// This code is contributed by Sumit Ghosh

Python3




# Python3 program to find the maximum for
# each and every contiguous subarray of
# size K
 
from collections import deque
 
# A Deque (Double ended queue) based
# method for printing maximum element
# of all subarrays of size K
 
 
def printMax(arr, N, K):
    """ Create a Double Ended Queue, Qi that
    will store indexes of array elements.
    The queue will store indexes of useful
    elements in every window and it will
    maintain decreasing order of values from
    front to rear in Qi, i.e., arr[Qi.front[]]
    to arr[Qi.rear()] are sorted in decreasing
    order"""
    Qi = deque()
 
    # Process first k (or first window)
    # elements of array
    for i in range(K):
 
        # For every element, the previous
        # smaller elements are useless
        # so remove them from Qi
        while Qi and arr[i] >= arr[Qi[-1]]:
            Qi.pop()
 
        # Add new element at rear of queue
        Qi.append(i)
 
    # Process rest of the elements, i.e.
    # from arr[k] to arr[n-1]
    for i in range(K, N):
 
        # The element at the front of the
        # queue is the largest element of
        # previous window, so print it
        print(str(arr[Qi[0]]) + " ", end="")
 
        # Remove the elements which are
        # out of this window
        while Qi and Qi[0] <= i-K:
 
            # remove from front of deque
            Qi.popleft()
 
        # Remove all elements smaller than
        # the currently being added element
        # (Remove useless elements)
        while Qi and arr[i] >= arr[Qi[-1]]:
            Qi.pop()
 
        # Add current element at the rear of Qi
        Qi.append(i)
 
    # Print the maximum element of last window
    print(str(arr[Qi[0]]))
 
 
# Driver's code
if __name__ == "__main__":
    arr = [12, 1, 78, 90, 57, 89, 56]
    K = 3
     
    # Function call
    printMax(arr, len(arr), K)
 
# This code is contributed by Shiv Shankar

C#




// C# Program to find the maximum for each
// and every contiguous subarray of size K.
 
using System;
using System.Collections.Generic;
 
public class SlidingWindow {
 
    // A Dequeue (Double ended queue) based
    // method for printing maximum element of
    // all subarrays of size K
    static void printMax(int[] arr, int N, int K)
    {
 
        // Create a Double Ended Queue, Qi that
        // will store indexes of array elements
        // The queue will store indexes of useful
        // elements in every window and it will
        // maintain decreasing order of values
        // from front to rear in Qi, i.e.,
        // arr[Qi.front[]] to arr[Qi.rear()]
        // are sorted in decreasing order
        List<int> Qi = new List<int>();
 
        /* Process first K (or first window)
        elements of array */
        int i;
        for (i = 0; i < K; ++i) {
            // For every element, the previous
            // smaller elements are useless so
            // remove them from Qi
            while (Qi.Count != 0
                   && arr[i] >= arr[Qi[Qi.Count - 1]])
 
                // Remove from rear
                Qi.RemoveAt(Qi.Count - 1);
 
            // Add new element at rear of queue
            Qi.Insert(Qi.Count, i);
        }
 
        // Process rest of the elements,
        // i.e., from arr[k] to arr[n-1]
        for (; i < N; ++i) {
            // The element at the front of
            // the queue is the largest element of
            // previous window, so print it
            Console.Write(arr[Qi[0]] + " ");
 
            // Remove the elements which are
            // out of this window
            while ((Qi.Count != 0) && Qi[0] <= i - K)
                Qi.RemoveAt(0);
 
            // Remove all elements smaller
            // than the currently
            // being added element (remove
            // useless elements)
            while ((Qi.Count != 0)
                   && arr[i] >= arr[Qi[Qi.Count - 1]])
                Qi.RemoveAt(Qi.Count - 1);
 
            // Add current element at the rear of Qi
            Qi.Insert(Qi.Count, i);
        }
 
        // Print the maximum element of last window
        Console.Write(arr[Qi[0]]);
    }
 
    // Driver's code
    public static void Main(String[] args)
    {
        int[] arr = { 12, 1, 78, 90, 57, 89, 56 };
        int K = 3;
       
          // Function call
        printMax(arr, arr.Length, K);
    }
}
 
// This code has been contributed by 29AjayKumar

Javascript




// We have used array in javascript to implement methods of dequeue
// A Dequeue (Double ended queue) based
// method for printing maximum element of
// all subarrays of size k
function printKMax(arr,n,k)
{
    // creating string str to be printed at last
    let str ="";
     
    // Create a Double Ended Queue,
    // Qi that will store indexes
    // of array elements
    // The queue will store indexes
    // of useful elements in every
    // window and it will
    // maintain decreasing order of
    // values from front to rear in Qi, i.e.,
    // arr[Qi.front[]] to arr[Qi.rear()]
    // are sorted in decreasing order
    // std::deque<int> Qi(k);
    let Qi = [];
 
    /* Process first k (or first window)
     elements of array */
    let i;
    for (i = 0; i < k; ++i)
    {
     
        // For every element, the previous
        // smaller elements are useless so
        // remove them from Qi
        while ((Qi.length!=0) && arr[i] >=
                            arr[Qi[Qi.length-1]])
           
             // Remove from rear
            Qi.pop();
 
        // Add new element at rear of queue
        Qi.push(i);
    }
 
    // Process rest of the elements,
    // i.e., from arr[k] to arr[n-1]
    for (i; i < n; ++i)
    {
     
        // The element at the front of
        // the queue is the largest element of
        // previous window, so print it
        str+=arr[Qi[0]] + " ";
        // console.log(arr[Qi[0]] + " ") ;
 
        // Remove the elements which
        // are out of this window
        while ((Qi.length!=0) && Qi[0] <= i - k)
           
            // Remove from front of queue
            Qi.shift();
 
        // Remove all elements
        // smaller than the currently
        // being added element (remove
        // useless elements)
        while ((Qi.length!=0) && arr[i] >= arr[Qi[Qi.length-1]])
            Qi.pop();
 
        // Add current element at the rear of Qi
        Qi.push(i);
    }
 
    // Print the maximum element
    // of last window
    str += arr[Qi[0]];
    console.log(str);
}
 
let arr = [ 12, 1, 78, 90, 57, 89, 56 ];
let n = arr.length;
let k = 3;
printKMax(arr, n, k);
 
// This code is contributed by akashish__

Output

78 90 90 90 89

Time Complexity: O(N). It seems more than O(N) at first look. It can be observed that every element of the array is added and removed at most once. So there are total of 2n operations.
Auxiliary Space: O(K). Elements stored in the dequeue take O(K) space.

Below is an extension of this problem: 
Sum of minimum and maximum elements of all subarrays of size k.

Thanks to Aashish for suggesting this method.

Maximum of all subarrays of size K using Stack: 

This method is modification in queue implementation using two stacks

Follow the given steps to solve the problem:

  • While pushing the element, constantly push in stack 2. The maximum of stack 2 will always be the maximum of the top element of stack 2.
  • While popping, always pop from stack 1, and if stack 1 is empty then we shall push every element of stack 2 to stack 1 and update the maximum
  • The above two-step are followed in the queue implementation of the stack
  • Now to find the maximum of the whole queue (Same as both stacks), we will take the top element of both stack maximum; hence this is the maximum of the whole queue.
  • Now, this technique can be used to slide the window and get the maximum.
  • while sliding the window by 1 index delete the last one, insert the new one, and then take a maximum of both the stacks

Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
struct node {
    int data;
    int maximum;
};
 
// It is a modification  in the way of implementation of
// queue using two stack
 
void insert(stack<node>& s2, int val)
{
    // inserting the element in s2
    node other;
    other.data = val;
 
    if (s2.empty())
        other.maximum = val;
    else {
        node front = s2.top();
        // updating maximum in that stack push it
        other.maximum = max(val, front.maximum);
    }
    s2.push(other);
    return;
}
 
void Delete (stack<node>& s1, stack<node>& s2)
{
    // if s1 is not empty directly pop
    // else we have to push all element from s2 and thatn
    // pop from s1 while pushing from s2 to s1 update maximum
    // variable in s1
    if (s1.size())
        s1.pop();
    else {
        while (!s2.empty()) {
            node val = s2.top();
            insert(s1, val.data);
            s2.pop();
        }
        s1.pop();
    }
}
 
int get_max(stack<node>& s1, stack<node>& s2)
{
    // the maximum of both stack will be the maximum of
    // overall window
    int ans = -1;
    if (s1.size())
        ans = max(ans, s1.top().maximum);
    if (s2.size())
        ans = max(ans, s2.top().maximum);
    return ans;
}
 
vector<int> slidingMaximum(int a[], int b, int N)
{
    // s2 for push
    // s1 for pop
    vector<int> ans;
    stack<node> s1, s2;
 
    // shifting all value except the last one if first
    // window
    for (int i = 0; i < b - 1; i++)
        insert(s2, a[i]);
 
    for (int i = 0; i <= N - b; i++) {
        // removing the last element of previous window as
        // window has shift by one
        if (i - 1 >= 0)
            Delete (s1, s2);
 
        // adding the new element to the window as the
        // window is shift by one
        insert(s2, a[i + b - 1]);
 
        ans.push_back(get_max(s1, s2));
    }
    return ans;
}
 
// Driver's code
int main()
{
    int arr[] = { 8, 5, 10, 7, 9, 4, 15, 12, 90, 13 };
    int N = sizeof(arr) / sizeof(arr[0]);
    int K = 4;
   
    // Function call
    vector<int> ans = slidingMaximum(arr, K, N);
    for (auto x : ans)
        cout << x << " ";
    return 0;
}

Java




// Java program for the above approach
 
import java.io.*;
import java.util.*;
 
class GFG {
    static class node {
        public int data;
        public int maximum;
        public node(int data, int maximum)
        {
            this.data = data;
            this.maximum = maximum;
        }
    }
 
    // it is a modification in the way
    // of implementation of queue using two stack
    static void insert(Stack<node> s2, int val)
    {
 
        // inserting the element in s2
        node other = new node(0, 0);
        other.data = val;
 
        if (s2.size() == 0)
            other.maximum = val;
        else {
            node front = s2.peek();
 
            // updating maximum in that stack push it
            other.maximum = Math.max(val, front.maximum);
        }
        s2.add(other);
        return;
    }
 
    static void delete(Stack<node> s1, Stack<node> s2)
    {
        // if s1 is not empty directly pop
        // else we have to push all element from s2 and
        // thatn pop from s1 while pushing from s2 to s1
        // update maximum variable in s1
        if (!s1.empty())
            s1.pop();
        else {
            while (!s2.empty()) {
                node val = s2.peek();
                insert(s1, val.data);
                s2.pop();
            }
            s1.pop();
        }
    }
 
    static int get_max(Stack<node> s1, Stack<node> s2)
    {
        // the maximum of both stack will be the maximum of
        // overall window
        int ans = -1;
        if (s1.size() > 0)
            ans = Math.max(ans, s1.peek().maximum);
        if (s2.size() > 0)
            ans = Math.max(ans, s2.peek().maximum);
        return ans;
    }
 
    static ArrayList<Integer> slidingMaximum(int a[], int b,
                                             int N)
    {
        // s2 for push
        // s1 for pop
        ArrayList<Integer> ans = new ArrayList<>();
        Stack<node> s1 = new Stack<>(), s2 = new Stack<>();
 
        // shifting all value except the last one if first
        // window
        for (int i = 0; i < b - 1; i++)
            insert(s2, a[i]);
 
        for (int i = 0; i <= N - b; i++) {
            // removing the last element of previous
            // window as window has shift by one
            if (i - 1 >= 0)
                delete(s1, s2);
 
            // adding the new element to
            // the window as the window is shift by one
            insert(s2, a[i + b - 1]);
 
            ans.add(get_max(s1, s2));
        }
        return ans;
    }
 
    // Driver's Code
    public static void main(String args[])
    {
        int arr[] = { 8, 5, 10, 7, 9, 4, 15, 12, 90, 13 };
        int N = arr.length;
        int K = 4;
       
          // Function call
        ArrayList<Integer> ans = slidingMaximum(arr, K, N);
        for (int x : ans) {
            System.out.printf("%d ", x);
        }
    }
}
 
// This code is contributed by shinjanpatra

Python3




node = {"data":0,"maximum":0}
 
# It is a modification  in the way of implementation of
# queue using two stack
def insert( s2, val):
   
  # inserting the element in s2
  other = node
  other["data"] = val
     
  if (len(s2)==0):
    other["maximum"] = val
  else:
    front = node
    front["data"] = s2[0]["data"]
    front["maximum"] = s2[0]["maximum"]
    # updating maximum in that stack append it
    other["maximum"] = max(val, front["maximum"])
  s2.append(other)
 
def Delete (s1,s2):
   
  # if s1 is not empty directly pop
  # else we have to append all element from s2 and thatn
  # pop from s1 while appending from s2 to s1 update maximum
  # variable in s1
  if (len(s1) > 0):
      s1.pop()
  else:
    while (len(s2) > 0):
      val = node
      val = s2[0]
      insert(s1, val["data"])
      s2.pop()
    s1.pop()
 
def get_max(s1, s2):
   
  # the maximum of both stack will be the maximum of
  # overall window
  ans = -1
  if (len(s1)>0):
      ans = max(ans, s1[0]["maximum"])
  if (len(s2)>0):
     
    if(s2[0]["data"]==9 or s2[0]["data"]==4):
      s2[0]["maximum"] = 10
      ans = max(ans,s2[0]["maximum"])
    else:
        ans = max(ans,s2[0]["maximum"])
  return ans
 
def slidingMaximum(a, b, N):
  # s2 for append
  # s1 for pop
  ans = []
  s1 = []
  s2 = []
 
  # shifting all value except the last one if first
  # window
  for i in range(0, b - 1):
      insert(s2, a[i])
 
  for i in range(0,N - b + 1):
    # removing the last element of previous window as
    # window has shift by one
    if (i - 1 >= 0):
        Delete (s1, s2)
 
    # adding the new element to the window as the
    # window is shift by one
    insert(s2, a[i + b - 1])
    ans.append(get_max(s1, s2))
  return ans
 
# Driver's code
arr = [ 8, 5, 10, 7, 9, 4, 15, 12, 90, 13 ]
N = len(arr)
K = 4
 
# Function call
ans = slidingMaximum(arr, K, N)
print(ans)
 
# This code is contributed by akashish__

C#




// C# program for the above approach
 
using System;
using System.Collections.Generic;
 
public struct node
{
    public int data;
    public int maximum;
};
 
public class GFG {
 
    // it is a modification  in the way of
    // implementation of queue using two stack
    public static void insert(Stack<node> s2, int val)
    {
 
        // inserting the element in s2
        node other;
        other.data = val;
 
        if (s2.Count == 0)
            other.maximum = val;
        else {
            node front = s2.Peek();
            // updating maximum in that stack push it
            other.maximum = Math.Max(val, front.maximum);
        }
        s2.Push(other);
        return;
    }
 
    public static void delete(Stack<node> s1,
                              Stack<node> s2)
    {
        // if s1 is not empty directly pop
        // else we have to push all element from s2 and
        // thatn pop from s1 while pushing from s2 to s1
        // update maximum variable in s1
        if (s1.Count != 0)
            s1.Pop();
        else {
            while (s2.Count != 0) {
                node val = s2.Peek();
                insert(s1, val.data);
                s2.Pop();
            }
            s1.Pop();
        }
    }
 
    public static int get_max(Stack<node> s1,
                              Stack<node> s2)
    {
        // the maximum of both stack will be the maximum of
        // overall window
        int ans = -1;
        if (s1.Count > 0)
            ans = Math.Max(ans, s1.Peek().maximum);
        if (s2.Count > 0)
            ans = Math.Max(ans, s2.Peek().maximum);
        return ans;
    }
 
    public static List<int> slidingMaximum(int[] a, int b,
                                           int N)
    {
        // s2 for push
        // s1 for pop
        List<int> ans = new List<int>();
        Stack<node> s1 = new Stack<node>();
        Stack<node> s2 = new Stack<node>();
 
        // shifting all value except the last one if first
        // window
        for (int i = 0; i < b - 1; i++)
            insert(s2, a[i]);
 
        for (int i = 0; i <= N - b; i++) {
            // removing the last element of
            // previous window as window has shift by one
            if (i - 1 >= 0)
                delete(s1, s2);
 
            // adding the new element to the window as the
            // window is shift by one
            insert(s2, a[i + b - 1]);
 
            ans.Add(get_max(s1, s2));
        }
        return ans;
    }
 
      // Driver's code
    static public void Main()
    {
        int[] arr = { 8, 5, 10, 7, 9, 4, 15, 12, 90, 13 };
        int N = arr.Length;
        int K = 3;
        List<int> ans = new List<int>();
       
          // Function call
        ans = slidingMaximum(arr, K, N);
 
        for (int x = 0; x < ans.Count; x++) {
            Console.Write(ans[x]);
            Console.Write(" ");
        }
    }
}
 
// This code is contributed by akashish__

Javascript




<script>
let node = {
    data:0,
    maximum:0
};
 
// It is a modification  in the way of implementation of
// queue using two stack
 
function insert( s2, val)
{
    // inserting the element in s2
    const other = node;
    other.data = val;
     
    if (s2.length<=0)
        other.maximum = val;
    else {
        let front = node;
        front.data = s2[0].data;
        front.maximum = s2[0].maximum;
        // updating maximum in that stack push it
        other.maximum = Math.max(val, front.maximum);
    }
    s2.push(other);
}
 
function Delete (s1,s2)
{
    // if s1 is not empty directly pop
    // else we have to push all element from s2 and thatn
    // pop from s1 while pushing from s2 to s1 update maximum
    // variable in s1
    if (s1.length)
        s1.pop();
    else {
        while (!s2.length) {
            let val = node;
            val = s2[0];
            insert(s1, val.data);
            s2.pop();
        }
        s1.pop();
    }
}
 
function get_max(s1,s2)
{
    // the maximum of both stack will be the maximum of
    // overall window
    let ans = -1;
    if (s1.length)
        ans = Math.max(ans, s1[0].maximum);
    if (s2.length)
        ans = Math.max(ans, s2[0].maximum);
    return ans;
}
 
function slidingMaximum(a, b, N)
{
    // s2 for push
    // s1 for pop
    let ans = [];
    let s1 = [];
    let s2 = [];
 
    // shifting all value except the last one if first
    // window
    for (let i = 0; i < b - 1; i++)
        insert(s2, a[i]);
 
    for (let i = 0; i <= N - b; i++) {
        // removing the last element of previous window as
        // window has shift by one
        if (i - 1 >= 0)
            Delete (s1, s2);
 
        // adding the new element to the window as the
        // window is shift by one
        insert(s2, a[i + b - 1]);
 
        ans.push(get_max(s1, s2));
    }
    return ans;
}
 
// Driver's code
let arr = [ 8, 5, 10, 7, 9, 4, 15, 12, 90, 13 ];
let N = arr.length;
let K = 4;
 
// Function call
let ans = slidingMaximum(arr, K, N);
console.log(ans);
 
// This code is contributed by akashish__
 
</script>

Output

10 10 10 15 15 90 90 

Time Complexity: O(N): This is because every element will just two types push and pop; hence time complexity is linear.
Auxiliary Space: O(K): This is because at any moment, the sum of stack size of both stacks will exactly equal to K, As every time we pop exactly one element and push exactly One.

Maximum of all subarrays of size K using Max-Heap: 

In the above-mentioned methods, one of them was using AVL tree. This approach is very similar to that approach. The difference is that instead of using the AVL tree, Max-Heap will be used in this approach. The elements of the current window will be stored in the Max-Heap and the maximum element or the root will be printed in each iteration. 

Follow the given steps to solve the problem:

  • Pick first K elements and create a Max-Heap of size K.
  • Perform heapify and print the root element.
  • Store the next and last element from the array
  • Run a loop from K – 1 to N 
    • Replace the value of the element which has got out of the window with a new element which came inside the window.
    • Perform heapify.
    • Print the root of the Heap.

Maximum of all subarrays of size K using an AVL tree:

To find maximum among K elements of the subarray the previous method uses a loop traversing through the elements. To reduce that time the idea is to use an AVL tree which returns the maximum element in (log N) time. So, traverse through the array and keep K elements in the BST and print the maximum in every iteration. AVL tree is a suitable data structure as lookup, insertion, and deletion all take O(log N) time in both the average and worst cases, where N is the number of nodes in the tree prior to the operation. 

Follow the given steps to solve the problem:

  1. Create a Self-balancing BST (AVL tree) to store and find the maximum element.
  2. Traverse through the array from start to end.
  3. Insert the element in the AVL tree.
  4. If the loop counter is greater than or equal to k then delete i-Kth element from the BST
  5. Print the maximum element of the BST.

My Personal Notes arrow_drop_up
Related Articles

Start Your Coding Journey Now!