Open In App

Maximum range length such that A[i] is maximum in given range for all i from [1, N]

Last Updated : 28 Jul, 2021
Summarize
Comments
Improve
Suggest changes
Share
Like Article
Like
Report

Given an array arr[] consisting of N distinct integers. For each i (0 ? i < n), find a range [l, r] such that A[i] = max(A[l], A[l+1], ..., A[r]) and l ? i ? r and r-l is maximized.

Examples:

Input: arr[] = {1, 3, 2}
Output: {0 0}, {0 2}, {2 2}
Explanation: For i=0, 1 is maximum in range [0, 0] only. For i=1, 3 is maximum in range [0, 2] and for i = 2, 2 is maximum in range [2, 2] only.

Input: arr[] = {1, 2}
Output: {0, 0}, {0, 1}

Naive Approach: The simplest approach to solve the problem is for each i, Iterate in the range [i+1, N-1] using variable r and iterate in the range [i-1, 0] using the variable l and terminate the loop when arr[l] > arr[i] and arr[r]>arr[i] respectively. The answer will be [l, r]

Time Complexity: O(N×N)
Auxiliary Space: O(1)

Efficient Approach: The above approach can be optimized further by using a stack data structure. Follow the steps below to solve the problem:

  • Initialize two vectors, say left and right that will store the left index and right index for each i respectively.
  • Initialize a stack of pairs, say s.
  • Insert INT_MAX and -1 as a pair in the stack.
  • Iterate in the range [0, N-1] using the variable i and perform the following steps:
    • While s.top().first<arr[i], pop the top element from the stack.
    • Modify the value of left[i] as s.top().second.
    • Push {arr[i], i} in the stack.
  • Now remove all the elements from the stack.
  • Insert INT_MAX and N in the stack as pairs.
  • Iterate in the range [N-1, 0] using the variable i and perform the following steps:
    • While s.top().first<arr[i], pop the top element from the stack.
    • Modify the value of right[i] as s.top().second.
    • Push {arr[i], i} in the stack.
  • Iterate in the range [0, N-1] using the variable i and print left[i] +1, right[i] -1 as the answer for ith element.

Below is the implementation of the above approach:

C++
// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;

// Function to find maximum range for
// each i such that arr[i] is max in range
void MaxRange(vector<int> A, int n)
{
    // Vector to store the left and right index
    // for each i such that left[i]>arr[i]
    // and right[i] > arr[i]
    vector<int> left(n), right(n);

    stack<pair<int, int> > s;
    s.push({ INT_MAX, -1 });

    // Traverse the array
    for (int i = 0; i < n; i++) {
        // While s.top().first<a[i]
        // remove the top element from
        // the stack
        while (s.top().first < A[i])
            s.pop();

        // Modify left[i]
        left[i] = s.top().second;
        s.push({ A[i], i });
    }
    // Clear the stack
    while (!s.empty())
        s.pop();
    s.push(make_pair(INT_MAX, n));

    // Traverse the array to find
    // right[i] for each i
    for (int i = n - 1; i >= 0; i--) {
        // While s.top().first<a[i]
        // remove the top element from
        // the stack
        while (s.top().first < A[i])
            s.pop();

        // Modify right[i]
        right[i] = s.top().second;
        s.push({ A[i], i });
    }

    // Print the value range for each i
    for (int i = 0; i < n; i++) {
        cout << left[i] + 1 << ' ' << right[i] - 1 << "\n";
    }
}

// Driver Code
int main()
{
    // Given Input
    vector<int> arr{ 1, 3, 2 };
    int n = arr.size();

    // Function Call
    MaxRange(arr, n);

    return 0;
}
Java
//Java program for above approach
import java.awt.*;
import java.util.*;
class GFG{
    static class pair<T, V>{
        T first;
        V second;
    }

    // Function to find maximum range for
    // each i such that arr[i] is max in range
    static void MaxRange(ArrayList<Integer> A, int n)
    {
        // Vector to store the left and right index
        // for each i such that left[i]>arr[i]
        // and right[i] > arr[i]

        int[] left = new int[n];
        int[] right = new int[n];

        Stack<pair<Integer,Integer>> s = new Stack<>();
        pair<Integer,Integer> x = new pair<>();
        x.first =Integer.MAX_VALUE;
        x.second = -1;
        s.push(x);

        // Traverse the array
        for (int i = 0; i < n; i++)
        {
          
            // While s.top().first<a[i]
            // remove the top element from
            // the stack
            while (s.peek().first < A.get(i))
                s.pop();

            // Modify left[i]
            left[i] = s.peek().second;
            pair<Integer,Integer> y = new pair<>();
            y.first = A.get(i);
            y.second = i;
            s.push(y);
        }
      
        // Clear the stack
        while (!s.empty())
            s.pop();
        pair<Integer,Integer> k = new pair<>();
        k.first =Integer.MAX_VALUE;
        k.second = n;
        s.push(k);

        // Traverse the array to find
        // right[i] for each i
        for (int i = n - 1; i >= 0; i--)
        {
          
            // While s.top().first<a[i]
            // remove the top element from
            // the stack
            while (s.peek().first < A.get(i))
                s.pop();

            // Modify right[i]
            right[i] = s.peek().second;
            pair<Integer,Integer> y = new pair<>();
            y.first = A.get(i);
            y.second = i;
            s.push(y);
        }
      
        // Print the value range for each i
        for (int i = 0; i < n; i++) {
            System.out.print(left[i]+1);
            System.out.print(" ");
            System.out.println(right[i]-1);
        }
    }

    // Driver Code
    public static void main(String[] args)
    {
      
        // Given Input
        ArrayList<Integer> arr = new ArrayList<>();
        arr.add(1);
        arr.add(3);
        arr.add(2);
        int n = arr.size();

        // Function Call
        MaxRange(arr, n);
    }
}

// This code is contributed by hritikrommie.
Python3
# Python 3 program for the above approach
import sys

# Function to find maximum range for
# each i such that arr[i] is max in range
def MaxRange(A, n):

    # Vector to store the left and right index
    # for each i such that left[i]>arr[i]
    # and right[i] > arr[i]
    left = [0] * n
    right = [0] * n

    s = []
    s.append((sys.maxsize, -1))

    # Traverse the array
    for i in range(n):
      
        # While s.top().first<a[i]
        # remove the top element from
        # the stack
        while (s[-1][0] < A[i]):
            s.pop()

        # Modify left[i]
        left[i] = s[-1][1]
        s.append((A[i], i))

    # Clear the stack
    while (len(s) != 0):
        s.pop()
    s.append((sys.maxsize, n))

    # Traverse the array to find
    # right[i] for each i
    for i in range(n - 1, -1, -1):
      
        # While s.top().first<a[i]
        # remove the top element from
        # the stack
        while (s[-1][0] < A[i]):
            s.pop()

        # Modify right[i]
        right[i] = s[-1][1]
        s.append((A[i], i))

    # Print the value range for each i
    for i in range(n):
        print(left[i] + 1, ' ', right[i] - 1)


# Driver Code
if __name__ == "__main__":
  
    # Given Input
    arr = [1, 3, 2]
    n = len(arr)

    # Function Call
    MaxRange(arr, n)

    # This code is contributed by ukasp.
C#
// C# program for the above approach.
using System;
using System.Collections;
using System.Collections.Generic;
class GFG
{
    
    // Function to find maximum range for
    // each i such that arr[i] is max in range
    static void MaxRange(List<int> A, int n)
    {
        // Vector to store the left and right index
        // for each i such that left[i]>arr[i]
        // and right[i] > arr[i]
        int[] left = new int[n];
        int[] right = new int[n];
     
        Stack s = new Stack();
        s.Push(new Tuple<int, int>(Int32.MaxValue, -1));
     
        // Traverse the array
        for (int i = 0; i < n; i++)
        {
          
            // While s.top().first<a[i]
            // remove the top element from
            // the stack
            while (((Tuple<int, int>)s.Peek()).Item1 < A[i])
                s.Pop();
     
            // Modify left[i]
            left[i] = ((Tuple<int, int>)s.Peek()).Item2;
            s.Push(new Tuple<int, int>(A[i], i));
        }
        // Clear the stack
        while (s.Count > 0)
            s.Pop();
        s.Push(new Tuple<int, int>(Int32.MaxValue, n));
     
        // Traverse the array to find
        // right[i] for each i
        for (int i = n - 1; i >= 0; i--) {
            // While s.top().first<a[i]
            // remove the top element from
            // the stack
            while (((Tuple<int, int>)s.Peek()).Item1 < A[i])
                s.Pop();
     
            // Modify right[i]
            right[i] = ((Tuple<int, int>)s.Peek()).Item2;
            s.Push(new Tuple<int, int>(A[i], i));
        }
     
        // Print the value range for each i
        for (int i = 0; i < n; i++) {
            Console.WriteLine((left[i] + 1) + " " + (right[i] - 1));
        }
    }
    
  static void Main ()
  {
    List<int> arr = new List<int>();
  
    // adding elements in firstlist
    arr.Add(1);
    arr.Add(3);
    arr.Add(2);
    
    int n = arr.Count;
 
    // Function Call
    MaxRange(arr, n);
  }
}

// This code is contributed by suresh07.
JavaScript
<script>

// Javascript program for the above approach

// Function to find maximum range for
// each i such that arr[i] is max in range
function MaxRange(A, n)
{
    
    // Vector to store the left and right index
    // for each i such that left[i]>arr[i]
    // and right[i] > arr[i]
    let left = new Array(n).fill(0), 
       right = new Array(n).fill(0);

    let s = [];
    s.push([Number.MAX_SAFE_INTEGER, -1]);

    // Traverse the array
    for(let i = 0; i < n; i++) 
    {
        
        // While s.top()[0]<a[i]
        // remove the top element from
        // the stack
        while (s[s.length - 1][0] < A[i])
            s.pop();

        // Modify left[i]
        left[i] = s[s.length - 1][1];
        s.push([A[i], i]);
    }
    
    // Clear the stack
    while (s.length)
        s.pop();
        
    s.push([Number.MAX_SAFE_INTEGER, n]);

    // Traverse the array to find
    // right[i] for each i
    for(let i = n - 1; i >= 0; i--)
    {
        
        // While s.top()[0]<a[i]
        // remove the top element from
        // the stack
        while (s[s.length - 1][0] < A[i])
            s.pop();

        // Modify right[i]
        right[i] = s[s.length - 1][1];
        s.push([A[i], i]);
    }

    // Print the value range for each i
    for(let i = 0; i < n; i++)
    {
        document.write(left[i] + 1 + " ")
        document.write(right[i] - 1 + "<br>")
    }
}

// Driver Code

// Given Input
let arr = [ 1, 3, 2 ];
let n = arr.length;

// Function Call
MaxRange(arr, n);

// This code is contributed by gfgking

</script>

Output: 
0 0
0 2
2 2

 

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


 


Similar Reads