Open In App

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

Last Updated : 24 Aug, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

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=7
Output: 
1 7 1 3 1 5 1
Explanation: 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: 

  1. For each index ‘i’, traverse to both the sides of the array until an element greater than arr[i] is found.
  2. 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:

  1. 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).
  2. Similarly, store the next greater element for each index on the left side of the array.
  3. 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++




// 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 index
vector<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 index
vector<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 subarray
void 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 code
int 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




// Java code for the above approach
import 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




# Python3 code for the above approach
 
# Function to compute next greater
# element indices on the right side
# on any index
def 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 index
def 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 subarray
def 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 code
if __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#




// C# code for the above approach
using 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.


Javascript




<script>
// Javascript code for the above approach
 
// Function to compute
// next greater element indices on the
// right side on any index
function 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 index
function 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 subarray
function 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
 
// Input
let arr = [62, 97, 49, 59, 54, 92, 21];
let N = arr.length;
 
// Function call
maximumSubarrayLength(arr, N);
 
// This code is contributed by _saurabh_jaiswal.
 
</script>


Output

1 7 1 3 1 5 1 

Time Complexity: O(N)
Auxiliary space: O(N)

 



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads