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:
- 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.
// 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 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 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# 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. |
<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> |
1 7 1 3 1 5 1
Time Complexity: O(N)
Auxiliary space: O(N)