Sliding Window Maximum (Maximum of all subarrays of size k) using stack in O(n) time
Give an array arr[] of N integers and another integer k ≤ N. The task is to find the maximum element of every sub-array of size k.
Examples:
Input: arr[] = {9, 7, 2, 4, 6, 8, 2, 1, 5}, k = 3
Output: 9 7 6 8 8 8 5
Window 1: {9, 7, 2}, max = 9
Window 2: {7, 2, 4}, max = 7
Window 3: {2, 4, 6}, max = 6
Window 4: {4, 6, 8}, max = 8
Window 5: {6, 8, 2}, max = 8
Window 6: {8, 2, 1}, max = 8
Window 7: {2, 1, 5}, max = 5
Input: arr[] = {6, 7, 5, 2, 1, 7, 2, 1, 10}, k = 2
Output: 7 7 5 2 7 7 2 10
Prerequisite: Next greater element
Approach: If you know for every index i an index j ≥ i such that max(a[i], a[i + 1], … a[j]) = a[i]. Lets call it max_upto[i]. Then if you want to know the maximum element in the sub-array of length k starting from ith index you can get it by checking every index starting from i to i + k – 1 for which max_upto[i] ≥ i + k – 1 (last index of that window).
Below is the implementation of the above approach:
C++
// C++ implementation of the approach #include <bits/stdc++.h> using namespace std; // Function to print the maximum for // every k size sub-array void print_max( int a[], int n, int k) { // max_upto array stores the index // upto which the maximum element is a[i] // i.e. max(a[i], a[i + 1], ... a[max_upto[i]]) = a[i] int max_upto[n]; // Update max_upto array similar to // finding next greater element stack< int > s; s.push(0); for ( int i = 1; i < n; i++) { while (!s.empty() && a[s.top()] < a[i]) { max_upto[s.top()] = i - 1; s.pop(); } s.push(i); } while (!s.empty()) { max_upto[s.top()] = n - 1; s.pop(); } int j = 0; for ( int i = 0; i <= n - k; i++) { // j < i is to check whether the // jth element is outside the window while (j < i || max_upto[j] < i + k - 1) j++; cout << a[j] << " " ; } cout << endl; } // Driver code int main() { int a[] = { 9, 7, 2, 4, 6, 8, 2, 1, 5 }; int n = sizeof (a) / sizeof ( int ); int k = 3; print_max(a, n, k); return 0; } |
Java
// Java implementation of the approach import java.util.*; class GFG { // Function to print the maximum for // every k size sub-array static void print_max( int a[], int n, int k) { // max_upto array stores the index // upto which the maximum element is a[i] // i.e. max(a[i], a[i + 1], ... a[max_upto[i]]) = a[i] int [] max_upto = new int [n]; // Update max_upto array similar to // finding next greater element Stack<Integer> s = new Stack<>(); s.push( 0 ); for ( int i = 1 ; i < n; i++) { while (!s.empty() && a[s.peek()] < a[i]) { max_upto[s.peek()] = i - 1 ; s.pop(); } s.push(i); } while (!s.empty()) { max_upto[s.peek()] = n - 1 ; s.pop(); } int j = 0 ; for ( int i = 0 ; i <= n - k; i++) { // j < i is to check whether the // jth element is outside the window while (j < i || max_upto[j] < i + k - 1 ) { j++; } System.out.print(a[j] + " " ); } System.out.println(); } // Driver code public static void main(String[] args) { int a[] = { 9 , 7 , 2 , 4 , 6 , 8 , 2 , 1 , 5 }; int n = a.length; int k = 3 ; print_max(a, n, k); } } // This code has been contributed by 29AjayKumar |
Python3
# Python3 implementation of the approach # Function to print the maximum for # every k size sub-array def print_max(a, n, k): # max_upto array stores the index # upto which the maximum element is a[i] # i.e. max(a[i], a[i + 1], ... a[max_upto[i]]) = a[i] max_upto = [ 0 for i in range (n)] # Update max_upto array similar to # finding next greater element s = [] s.append( 0 ) for i in range ( 1 ,n): while ( len (s) > 0 and a[s[ - 1 ]] < a[i]): max_upto[s[ - 1 ]] = i - 1 del s[ - 1 ] s.append(i) while ( len (s) > 0 ): max_upto[s[ - 1 ]] = n - 1 del s[ - 1 ] j = 0 for i in range (n - k + 1 ): # j < i is to check whether the # jth element is outside the window while (j < i or max_upto[j] < i + k - 1 ): j + = 1 print (a[j], end = " " ) print () # Driver code a = [ 9 , 7 , 2 , 4 , 6 , 8 , 2 , 1 , 5 ] n = len (a) k = 3 print_max(a, n, k) # This code is contributed by mohit kumar |
C#
// C# implementation of the approach using System; using System.Collections.Generic; class GFG { // Function to print the maximum for // every k size sub-array static void print_max( int []a, int n, int k) { // max_upto array stores the index // upto which the maximum element is a[i] // i.e. max(a[i], a[i + 1], ... a[max_upto[i]]) = a[i] int [] max_upto = new int [n]; // Update max_upto array similar to // finding next greater element Stack< int > s = new Stack< int >(); s.Push(0); for ( int i = 1; i < n; i++) { while (s.Count!=0 && a[s.Peek()] < a[i]) { max_upto[s.Peek()] = i - 1; s.Pop(); } s.Push(i); } while (s.Count!=0) { max_upto[s.Peek()] = n - 1; s.Pop(); } int j = 0; for ( int i = 0; i <= n - k; i++) { // j < i is to check whether the // jth element is outside the window while (j < i || max_upto[j] < i + k - 1) { j++; } Console.Write(a[j] + " " ); } Console.WriteLine(); } // Driver code public static void Main(String[] args) { int []a = {9, 7, 2, 4, 6, 8, 2, 1, 5}; int n = a.Length; int k = 3; print_max(a, n, k); } } // This code has been contributed by 29AjayKumar |
9 7 6 8 8 8 5
Recommended Posts:
- Sliding Window Maximum (Maximum of all subarrays of size k)
- Maximum subarray size, such that all subarrays of that size have sum less than k
- Maximum of all Subarrays of size k using set in C++ STL
- Maximum sum two non-overlapping subarrays of given size
- Sum of minimum and maximum elements of all subarrays of size k.
- Find maximum of minimum for every window size in a given array
- Find maximum in a stack in O(1) time and O(1) extra space
- Window Sliding Technique
- Find maximum in stack in O(1) without using additional stack
- Maximum possible sum of a window in an array such that elements of same window in other array are unique
- Sum of maximum of all subarrays | Divide and Conquer
- Number of subarrays whose minimum and maximum are same
- Maximum sum of lengths of non-overlapping subarrays with k as the max element.
- Maximum sum of non-overlapping subarrays of length atmost K
- Count of subarrays whose maximum element is greater than k
If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.