Maximum range subarray for each index in Array such that A[i] = min(A[L], A[L+1], … A[R])
Last Updated :
20 Aug, 2021
Given an array arr[] of N distinct integers, the task is to calculate for each index i (1≤i≤N) a range [L, R] such that arr[i] = min(arr[L], arr[L+1], … arr[R]), where L≤i≤R and R-L is maximized.
Examples:
Input: N = 3, arr[] = {1, 3, 2}
Output: 1 3
2 2
2 3
Explanation: 1 is minimum in the range [1, 3]
3 is minimum in the range [2, 2]
2 is minimum in range [2, 3]
Input: N = 3, arr[] = {4, 5, 6}
Output: 1 3
2 3
3 3
Approach: It can be observed that previous smaller and next smaller elements are required at each index to calculate the required range. The idea is to use stacks to find the previous greater and the next greater elements. Follow the steps below to solve the problem:
- Create two arrays, L[] and R[], to store the closest smaller element at left and the closest smaller element at the right of the current element respectively.
- Create a stack S, and add the index of the first element in it.
- Traverse the given array, arr[], and pop stack until the top of the stack, S is not smaller than the current element.
- Now set the closest smaller element at the left i.e L[i] as the top of S, and if S is empty, set it as 0. Push the current element into S.
- Similarly, traverse from the end in opposite direction and follow the same steps to fill the array, R[].
- Iterate in the range [1, N] and print L[i] and R[i] for each index i.
Below is the implementation for the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void rangeFinder( int arr[], int N)
{
int L[N];
int R[N];
stack< int > S;
L[0] = 0;
S.push(0);
for ( int i = 1; i < N; i++) {
while (!S.empty() && arr[S.top()] > arr[i])
S.pop();
if (!S.empty())
L[i] = S.top() + 1;
else
L[i] = 0;
S.push(i);
}
while (!S.empty())
S.pop();
R[N - 1] = N - 1;
S.push(N - 1);
for ( int i = N - 2; i >= 0; i--) {
while (!S.empty() && arr[S.top()] > arr[i])
S.pop();
if (!S.empty())
R[i] = S.top() - 1;
else
R[i] = N - 1;
S.push(i);
}
for ( int i = 0; i < N; i++) {
cout << L[i] + 1 << " " << R[i] + 1 << endl;
}
}
int main()
{
int arr[] = { 1, 3, 2 };
int N = sizeof (arr) / sizeof (arr[0]);
rangeFinder(arr, N);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG{
static void rangeFinder( int arr[], int N)
{
int [] L = new int [N];
int [] R = new int [N];
Stack<Integer> S = new Stack<Integer>();
L[ 0 ] = 0 ;
S.push( 0 );
for ( int i = 1 ; i < N; i++)
{
while (!S.empty() && arr[S.peek()] > arr[i])
S.pop();
if (!S.empty())
L[i] = S.peek() + 1 ;
else
L[i] = 0 ;
S.push(i);
}
while (!S.empty())
S.pop();
R[N - 1 ] = N - 1 ;
S.push(N - 1 );
for ( int i = N - 2 ; i >= 0 ; i--)
{
while (!S.empty() && arr[S.peek()] > arr[i])
S.pop();
if (!S.empty())
R[i] = S.peek() - 1 ;
else
R[i] = N - 1 ;
S.push(i);
}
for ( int i = 0 ; i < N; i++)
{
System.out.println((L[i] + 1 ) + " " +
(R[i] + 1 ));
}
}
public static void main(String[] args)
{
int arr[] = { 1 , 3 , 2 };
int N = arr.length;
rangeFinder(arr, N);
}
}
|
Python3
def rangeFinder(arr, N):
L = [ 0 for i in range (N)]
R = [ 0 for i in range (N)]
S = []
L[ 0 ] = 0
S.append( 0 )
for i in range ( 1 , N, 1 ):
while ( len (S) > 0 and
arr[S[ len (S) - 1 ]] > arr[i]):
S = S[: - 1 ]
if ( len (S) > 0 ):
L[i] = S[ len (S) - 1 ] + 1
else :
L[i] = 0
S.append(i)
while ( len (S) > 0 ):
S.pop()
R[N - 1 ] = N - 1
S.append(N - 1 )
i = N - 2
while (i > = 0 ):
while ( len (S) > 0 and
arr[S[ len (S) - 1 ]] > arr[i]):
S = S[: - 1 ]
if ( len (S) > 0 ):
R[i] = S[ len (S) - 1 ] - 1 ;
else :
R[i] = N - 1
S.append(i)
i - = 1
for i in range (N):
print (L[i] + 1 , R[i] + 1 )
if __name__ = = '__main__' :
arr = [ 1 , 3 , 2 ]
N = len (arr)
rangeFinder(arr, N)
|
C#
using System;
using System.Collections;
class GFG {
static void rangeFinder( int [] arr, int N)
{
int [] L = new int [N];
int [] R = new int [N];
Stack S = new Stack();
L[0] = 0;
S.Push(0);
for ( int i = 1; i < N; i++)
{
while (S.Count > 0 && arr[( int )S.Peek()] > arr[i])
S.Pop();
if (S.Count > 0)
L[i] = ( int )S.Peek() + 1;
else
L[i] = 0;
S.Push(i);
}
while (S.Count > 0)
S.Pop();
R[N - 1] = N - 1;
S.Push(N - 1);
for ( int i = N - 2; i >= 0; i--)
{
while (S.Count > 0 && arr[( int )S.Peek()] > arr[i])
S.Pop();
if (S.Count > 0)
R[i] = ( int )S.Peek() - 1;
else
R[i] = N - 1;
S.Push(i);
}
for ( int i = 0; i < N; i++)
{
Console.WriteLine((L[i] + 1) + " " + (R[i] + 1));
}
}
static void Main()
{
int [] arr = { 1, 3, 2 };
int N = arr.Length;
rangeFinder(arr, N);
}
}
|
Javascript
<script>
function rangeFinder(arr, N) {
let L = new Array(N).fill(0);
let R = new Array(N).fill(0);
let S = [];
L[0] = 0;
S.push(0);
for (let i = 1; i < N; i++) {
while (S.length && arr[S[S.length - 1]] > arr[i])
S.pop();
if (S.length)
L[i] = S[S.length - 1] + 1;
else
L[i] = 0;
S.push(i);
}
while (S.length)
S.pop();
R[N - 1] = N - 1;
S.push(N - 1);
for (let i = N - 2; i >= 0; i--) {
while (S.length && arr[S[S.length - 1]] > arr[i])
S.pop();
if (S.length)
R[i] = S[S.length - 1] - 1;
else
R[i] = N - 1;
S.push(i);
}
for (let i = 0; i < N; i++) {
document.write(L[i] + 1 + " " )
document.write(R[i] + 1 + "<br>" );
}
}
let arr = [1, 3, 2];
let N = arr.length;
rangeFinder(arr, N);
</script>
|
Output:
1 3
2 2
2 3
Time Complexity: O(N)
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...