Length of longest subarray for each index in Array where element at that index is largest - GeeksforGeeks

24 Aug, 2021
Given an array arr[] of size N, the task is to calculate, for i(0<=i<N), the maximum length of a subarray containing arr[i], where arr[i] is the maximum element.
Example:
Input : arr[ ] = {62, 97, 49, 59, 54, 92, 21}, N=7Output: 1 7 1 3 1 5 1Explanation: The maximum length of subarray in which 1st index element is maximum is 1, the subarray consisting of only first element.For second element, i.e. 97, maximum length of subarray = 7. We can observe that 97 is the maximum element in the array A.For third element, only 49 can be in the subarray. Hence, maximum length that is possible = 1.For fourth element, subarray [49, 59, 54] is possible where 59 is the maximum number. Hence, length = 3.Likewise, we calculate for each index in the array.
Input: arr[]={1, 4, 5, 2, 3}Output:1 2 5 1 2
Naive Approach: 
For each index ‘i’, traverse to both the sides of the array until an element greater than arr[i] is found.Count the number of elements in the range, which will be the maximum length of a subarray in which arr[i] is the greatest element.
For each index ‘i’, traverse to both the sides of the array until an element greater than arr[i] is found.
Count the number of elements in the range, which will be the maximum length of a subarray in which arr[i] is the greatest element.
Time Complexity: O(N2),
Efficient approach: The idea is to use the stack data structure to calculate the next greater element for each index(once on the left and once on the right). 
For example,
Let arr[]={1, 3, 1, 2, 1, 5}, for i=3, the next greater element on the left is at index 1 and on the right is at index 5. Thus, the length of the subarray in which it is the largest is 5-1-1=3 i.e from indices 2 to 4 or {1, 2, 1}
Follow the steps below to solve the problem:
Find the index of the next greater element for each index and store it in an array using stack data structure for each i(0<=i<N).Similarly, store the next greater element for each index on the left side of the array.Traverse the array and for every index, i, print the number of elements between the next greater element on the left side and the next greater element on the right side.
Find the index of the next greater element for each index and store it in an array using stack data structure for each i(0<=i<N).
Similarly, store the next greater element for each index on the left side of the array.
Traverse the array and for every index, i, print the number of elements between the next greater element on the left side and the next greater element on the right side.
C++
Java
Python3
C#
Javascript
// C++ code for the above approach#include <bits/stdc++.h>using namespace std; // Function to compute// next greater element indices on the// right side on any indexvector<int> rightGreaterElement(int arr[], int n){    // to store the elements of array arr    // with their index    vector<pair<int, int> > B(n);    for (int i = 0; i < n; i++) {        B[i].first = arr[i];        B[i].second = i;    }     // to store indices of next greater element    // on the right side    vector<int> vec(n, -1);     // to store the pairs    stack<pair<int, int> > st;    for (int i = 0; i < n; i++) {         // if the stack is empty,        // push the pair        if (st.empty()) {            st.push(B[i]);        }        else {             // Pop and assign till            // the top is smaller            while (!st.empty()                   && st.top().first < B[i].first) {                vec[st.top().second] = B[i].second;                st.pop();            }            st.push(B[i]);        }    }     // assign n to element    // having no next greater element    while (!st.empty()) {        vec[st.top().second] = n;        st.pop();    }     // return the vector    return vec;} // Function to compute next greater element// indices on the left side on any indexvector<int> leftGreaterElement(int arr[], int n){    // store the elements of array arr    // with their index    vector<pair<int, int> > B(n);    for (int i = 0; i < n; i++) {        B[i].first = arr[i];        B[i].second = i;    }     // array to store indices of next    // greater element on the left side    vector<int> vec(n, -1);     // stack to store the pairs    stack<pair<int, int> > st;     for (int i = n - 1; i >= 0; i--) {         // if the stack is empty, push the pair        if (st.empty()) {            st.push(B[i]);        }        else {             // pop and assign till top is smaller            while (!st.empty()                   && st.top().first < B[i].first) {                vec[st.top().second] = B[i].second;                st.pop();            }            st.push(B[i]);        }    }     // assign -1 to element having    // no next greater element    while (!st.empty()) {        vec[st.top().second] = -1;        st.pop();    }     // returning the vector    // with indices of next greater    // elements on the left side.    return vec;} // Function to print the maximum// length of subarrays for all// indices where A[i] is the// maximum element in the subarrayvoid maximumSubarrayLength(int arr[], int N){    // array having index of next    // greater element on the right side.    vector<int> right = rightGreaterElement(arr, N);     // array having index of next    // greater element on the left side.    vector<int> left = leftGreaterElement(arr, N);     // print the range between the    // next greater elements on both the sides.    for (int i = 0; i < N; i++) {        int l = left[i];        int r = right[i];        cout << r - l - 1 << " ";    }} // Driver codeint main(){    // Input    int arr[] = { 62, 97, 49, 59, 54, 92, 21 };    int N = sizeof(arr) / sizeof(arr[0]);     // Function call    maximumSubarrayLength(arr, N);    return 0;}
// Java code for the above approachimport java.util.*;import java.awt.Point;public class Main{    // Function to compute    // next greater element indices on the    // right side on any index    static int[] rightGreaterElement(int[] arr, int n)    {               // to store the elements of array arr        // with their index        int[][] B = new int[n][2];        for (int i = 0; i < n; i++) {            B[i][0] = arr[i];            B[i][1] = i;        }               // to store indices of next greater element        // on the right side        int[] vec = new int[n];        Arrays.fill(vec, -1);               // to store the pairs        Stack<Point> st = new Stack<Point>();        for (int i = 0; i < n; i++) {                   // if the stack is empty,            // push the pair            if (st.size() == 0) {                st.push(new Point(B[i][0], B[i][1]));            }            else {                       // Pop and assign till                // the top is smaller                while (st.size() > 0 && (st.peek()).x < B[i][0]) {                    vec[(st.peek()).y] = B[i][1];                    st.pop();                }                st.push(new Point(B[i][0], B[i][1]));            }        }               // assign n to element        // having no next greater element        while (st.size() > 0) {            vec[(st.peek()).y] = n;            st.pop();        }               // return the vector        return vec;    }          // Function to compute next greater element    // indices on the left side on any index    static int[] leftGreaterElement(int[] arr, int n)    {        // store the elements of array arr        // with their index        int[][] B = new int[n][2];        for (int i = 0; i < n; i++) {            B[i][0] = arr[i];            B[i][1] = i;        }               // array to store indices of next        // greater element on the left side        int[] vec = new int[n];        Arrays.fill(vec, -1);               // stack to store the pairs        Stack<Point> st = new Stack<Point>();               for (int i = n - 1; i >= 0; i--) {                   // if the stack is empty, push the pair            if (st.size() == 0) {                st.push(new Point(B[i][0], B[i][1]));            }            else {                       // pop and assign till top is smaller                while (st.size() > 0 && (st.peek()).x < B[i][0]) {                    vec[(st.peek()).y] = B[i][1];                    st.pop();                }                st.push(new Point(B[i][0], B[i][1]));            }        }               // assign -1 to element having        // no next greater element        while (st.size() > 0) {            vec[(st.peek()).y] = -1;            st.pop();        }               // returning the vector        // with indices of next greater        // elements on the left side.        return vec;    }          // Function to print the maximum    // length of subarrays for all    // indices where A[i] is the    // maximum element in the subarray    static void maximumSubarrayLength(int[] arr, int N)    {        // array having index of next        // greater element on the right side.        int[] right = rightGreaterElement(arr, N);               // array having index of next        // greater element on the left side.        int[] left = leftGreaterElement(arr, N);               // print the range between the        // next greater elements on both the sides.        for (int i = 0; i < N; i++) {            int l = left[i];            int r = right[i];            System.out.print((r - l - 1) + " ");        }    }         public static void main(String[] args) {        // Input        int[] arr = { 62, 97, 49, 59, 54, 92, 21 };        int N = arr.length;               // Function call        maximumSubarrayLength(arr, N);    }} // This code is contributed by mukesh07.
# Python3 code for the above approach # Function to compute next greater# element indices on the right side# on any indexdef rightGreaterElement(arr, n):         # To store the elements of array arr    # with their index    B = [[0, 0] for i in range(n)]         for i in range(n):        B[i][0] = arr[i]        B[i][1] = i     # To store indices of next greater element    # on the right side    vec = [-1 for i in range(n)]     # To store the pairs    st = []    for i in range(n):                 # If the stack is empty,        # push the pair        if (len(st) == 0):            st.append(B[i])        else:             # Pop and assign till            # the top is smaller            while (len(st) > 0 and st[-1][0] < B[i][0]):                vec[st[-1][1]] = B[i][1]                st.pop()                             st.append(B[i])     # Assign n to element    # having no next greater element    while (len(st) > 0):        vec[st[-1][1]] = n        st.pop()     # Return the vector    return vec # Function to compute next greater element# indices on the left side on any indexdef leftGreaterElement(arr, n):         # Store the elements of array arr    # with their index    B = [[0,0] for i in range(n)]    for i in range(n):        B[i][0] = arr[i]        B[i][1] = i     # Array to store indices of next    # greater element on the left side    vec = [-1 for i in range(n)]     # Stack to store the pairs    st = []     i = n - 1         while(i >= 0):                 # If the stack is empty, push the pair        if (len(st) == 0):            st.append(B[i])        else:             # Pop and assign till top is smaller            while (len(st) > 0 and st[-1][0] < B[i][0]):                vec[st[-1][1]] = B[i][1]                st.pop()                             st.append(B[i])                     i -= 1     # Assign -1 to element having    # no next greater element    while (len(st) > 0):        vec[st[-1][1]] = -1        st.pop()     # Returning the vector    # with indices of next greater    # elements on the left side.    return vec # Function to print the maximum# length of subarrays for all# indices where A[i] is the# maximum element in the subarraydef maximumSubarrayLength(arr, N):         # Array having index of next    # greater element on the right side.    right = rightGreaterElement(arr, N)     # Array having index of next    # greater element on the left side.    left = leftGreaterElement(arr, N)     # Print the range between the    # next greater elements on both the sides.    for i in range(N):        l = left[i]        r = right[i]        print(r - l - 1, end = " ") # Driver codeif __name__ == '__main__':         # Input    arr = [ 62, 97, 49, 59, 54, 92, 21 ]    N = len(arr)     # Function call    maximumSubarrayLength(arr, N)     # This code is contributed by ipg2016107
// C# code for the above approachusing System;using System.Collections;class GFG {         // Function to compute    // next greater element indices on the    // right side on any index    static int[] rightGreaterElement(int[] arr, int n)    {        // to store the elements of array arr        // with their index        int[,] B = new int[n,2];        for (int i = 0; i < n; i++) {            B[i,0] = arr[i];            B[i,1] = i;        }              // to store indices of next greater element        // on the right side        int[] vec = new int[n];        Array.Fill(vec, -1);              // to store the pairs        Stack st = new Stack();        for (int i = 0; i < n; i++) {                  // if the stack is empty,            // push the pair            if (st.Count == 0) {                st.Push(new Tuple<int,int>(B[i,0], B[i,1]));            }            else {                      // Pop and assign till                // the top is smaller                while (st.Count > 0                       && ((Tuple<int,int>)st.Peek()).Item1 < B[i,0]) {                    vec[((Tuple<int,int>)st.Peek()).Item2] = B[i,1];                    st.Pop();                }                st.Push(new Tuple<int,int>(B[i,0], B[i,1]));            }        }              // assign n to element        // having no next greater element        while (st.Count > 0) {            vec[((Tuple<int,int>)st.Peek()).Item2] = n;            st.Pop();        }              // return the vector        return vec;    }         // Function to compute next greater element    // indices on the left side on any index    static int[] leftGreaterElement(int[] arr, int n)    {        // store the elements of array arr        // with their index        int[,] B = new int[n,2];        for (int i = 0; i < n; i++) {            B[i,0] = arr[i];            B[i,1] = i;        }              // array to store indices of next        // greater element on the left side        int[] vec = new int[n];        Array.Fill(vec, -1);              // stack to store the pairs        Stack st = new Stack();              for (int i = n - 1; i >= 0; i--) {                  // if the stack is empty, push the pair            if (st.Count == 0) {                st.Push(new Tuple<int,int>(B[i,0], B[i,1]));            }            else {                      // pop and assign till top is smaller                while (st.Count > 0                       && ((Tuple<int,int>)st.Peek()).Item1 < B[i,0]) {                    vec[((Tuple<int,int>)st.Peek()).Item2] = B[i,1];                    st.Pop();                }                st.Push(new Tuple<int,int>(B[i,0], B[i,1]));            }        }              // assign -1 to element having        // no next greater element        while (st.Count > 0) {            vec[((Tuple<int,int>)st.Peek()).Item2] = -1;            st.Pop();        }              // returning the vector        // with indices of next greater        // elements on the left side.        return vec;    }         // Function to print the maximum    // length of subarrays for all    // indices where A[i] is the    // maximum element in the subarray    static void maximumSubarrayLength(int[] arr, int N)    {        // array having index of next        // greater element on the right side.        int[] right = rightGreaterElement(arr, N);              // array having index of next        // greater element on the left side.        int[] left = leftGreaterElement(arr, N);              // print the range between the        // next greater elements on both the sides.        for (int i = 0; i < N; i++) {            int l = left[i];            int r = right[i];            Console.Write((r - l - 1) + " ");        }    }   static void Main()  {         // Input    int[] arr = { 62, 97, 49, 59, 54, 92, 21 };    int N = arr.Length;      // Function call    maximumSubarrayLength(arr, N);  }} // This code is contributed by divyesh072019.
<script>// Javascript code for the above approach // Function to compute// next greater element indices on the// right side on any indexfunction rightGreaterElement(arr, n) {    // to store the elements of array arr    // with their index    let B = new Array(n).fill(0).map(() => new Array(2).fill(0));    for (let i = 0; i < n; i++) {        B[i][0] = arr[i];        B[i][1] = i;    }     // to store indices of next greater element    // on the right side    let vec = new Array(n).fill(-1);     // to store the pairs    let st = [];    for (let i = 0; i < n; i++) {         // if the stack is empty,        // push the pair        if (st.length == 0) {            st.push(B[i]);        }        else {             // Pop and assign till            // the top is smaller            while (st.length > 0                && st[st.length - 1][0] < B[i][0]) {                vec[st[st.length - 1][1]] = B[i][1];                st.pop();            }            st.push(B[i]);        }    }     // assign n to element    // having no next greater element    while (st.length > 0) {        vec[st[st.length - 1][1]] = n;        st.pop();    }     // return the vector    return vec;} // Function to compute next greater element// indices on the left side on any indexfunction leftGreaterElement(arr, n) {    // store the elements of array arr    // with their index    let B = new Array(n).fill(0).map(() => new Array(2));    for (let i = 0; i < n; i++) {        B[i][0] = arr[i];        B[i][1] = i;    }     // array to store indices of next    // greater element on the left side    let vec = new Array(n).fill(-1);     // stack to store the pairs    let st = [];     for (let i = n - 1; i >= 0; i--) {         // if the stack is empty, push the pair        if (st.length == 0) {            st.push(B[i]);        }        else {             // pop and assign till top is smaller            while (st.length > 0                && st[st.length - 1][0] < B[i][0]) {                vec[st[st.length - 1][1]] = B[i][1];                st.pop();            }            st.push(B[i]);        }    }     // assign -1 to element having    // no next greater element    while (st.length > 0) {        vec[st[st.length - 1][1]] = -1;        st.pop();    }     // returning the vector    // with indices of next greater    // elements on the left side.    return vec;} // Function to print the maximum// length of subarrays for all// indices where A[i] is the// maximum element in the subarrayfunction maximumSubarrayLength(arr, N){     // array having index of next    // greater element on the right side.    let right = rightGreaterElement(arr, N);     // array having index of next    // greater element on the left side.    let left = leftGreaterElement(arr, N);     // print the range between the    // next greater elements on both the sides.    for (let i = 0; i < N; i++) {        let l = left[i];        let r = right[i];        document.write(r - l - 1 + " ");    }} // Driver code // Inputlet arr = [62, 97, 49, 59, 54, 92, 21];let N = arr.length; // Function callmaximumSubarrayLength(arr, N); // This code is contributed by _saurabh_jaiswal. </script>
1 7 1 3 1 5 1 
Time Complexity: O(N)Auxiliary space: O(N)
 
ipg2016107
_saurabh_jaiswal
divyesh072019
mukesh07
subarray
Arrays
Stack
Arrays
Stack
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Count pairs with given sum
Chocolate Distribution Problem
Window Sliding Technique
Reversal algorithm for array rotation
Next Greater Element
Stack Class in Java
Stack in Python
Check for Balanced Brackets in an expression (well-formedness) using Stack
Stack | Set 2 (Infix to Postfix)
Queue using Stacks