Find next Smaller of next Greater in an array

3.1

Given array of integer, find the next smaller of next greater element of every element in array.

Note : Elements for which no greater element exists or no smaller of greater element exist, print -1.

Examples:

Input : arr[] = {5, 1, 9, 2, 5, 1, 7}
Output:          2  2 -1  1 -1 -1 -1
Explanation :  
Next Greater ->      Right Smaller 
   5 ->  9             9 ->  2 
   1 ->  9             9 ->  2
   9 -> -1            -1 -> -1
   2 ->  5             5 ->  1
   5 ->  7             7 -> -1
   1 ->  7             7 -> -1
   7 -> -1            -1 -> -1 

Input  : arr[] = {4, 8, 2, 1, 9, 5, 6, 3}
Output :          2  5  5  5 -1  3 -1 -1 

A simple solution is to iterate through all elements. For every element, find the next greater element of current element and then find right smaller element for current next greater element. Time taken of this solution is O(n2).

An efficient solution takes O(n) time. Ee notice that it is the combination of Next greater element & next smaller element in array.

Let input array be 'arr[]' and size of array be 'n'
find next greatest element of every element 

 step 1 : Create an empty stack (S) in which we store the indexes
          and NG[] that is user to store the indexes of NGE
          of every element.

 step 2 : Traverse the array in reverse order 
            where i goes from (n-1 to 0)

        a) While S is nonempty and the top element of 
           S is smaller than or equal to 'arr[i]':
              pop S

        b) If S is empty 
             arr[i] has no greater element
             NG[i] = -1

        c) else we have next greater element
             NG[i] = S.top() // here we store the index of NGE

        d). push current element index in stack 
           S.push(i)

Find Right smaller element of every element      
    
  step 3 : create an array RS[] used to store the index of
           right smallest element 

  step 4 : we repeat step (1 & 2)  with little bit of
           modification in step 1 & 2 .
           they are :

          a). we use RS[] in place of NG[].

          b). In step (2.a)
              we pop element form stack S  while S is not
              empty or the top element of S is greater then 
              or equal to 'arr[i]'  

  step 5 . compute all RSE of NGE :

           where i goes from 0 to n-1 
           if NG[ i ] != -1 && RS[ NG [ i]] ! =-1
              print arr[RS[NG[i]]]
          else
              print -1
                   

Below is C++ implementation of above idea

// C++ Program to find Right smaller element of next
// greater element
#include<bits/stdc++.h>
using namespace std;

// function find Next greater element
void nextGreater(int arr[], int n, int next[], char order)
{
    // create empty stack
    stack<int> S;

    // Traverse all array elements in reverse order
    // order == 'G' we compute next greater elements of
    //              every element
    // order == 'S' we compute right smaller element of
    //              every element
    for (int i=n-1; i>=0; i--)
    {
        // Keep removing top element from S while the top
        // element is smaller then or equal to arr[i] (if Key is G)
        // element is greater then or equal to arr[i] (if order is S)
        while (!S.empty() &&
              ((order=='G')? arr[S.top()] <= arr[i]:
                           arr[S.top()] >= arr[i]))
            S.pop();

        // store the next greater element of current element
        if (!S.empty())
            next[i] = S.top();

        // If all elements in S were smaller than arr[i]
        else
            next[i] = -1;

        // Push this element
        S.push(i);
    }
}

// Function to find Right smaller element of next greater
// element
void nextSmallerOfNextGreater(int arr[], int n)
{
    int NG[n]; // stores indexes of next greater elements
    int RS[n]; // stores indexes of right smaller elements

    // Find next greater element
    // Here G indicate next greater element
    nextGreater(arr, n, NG, 'G');

    // Find right smaller element
    // using same function nextGreater()
    // Here S indicate right smaller elements
    nextGreater(arr, n, RS, 'S');

    // If NG[i] == -1 then there is no smaller element
    // on right side. We can find Right smaller of next
    // greater by arr[RS[NG[i]]]
    for (int i=0; i< n; i++)
    {
        if (NG[i] != -1 && RS[NG[i]] != -1)
            cout << arr[RS[NG[i]]] << " ";
        else
            cout<<"-1"<<" ";
    }
}

// Driver program
int main()
{
    int arr[] = {5, 1, 9, 2, 5, 1, 7};
    int n = sizeof(arr)/sizeof(arr[0]);
    nextSmallerOfNextGreater(arr, n);
    return 0;
} 

Output:

2 2 -1 1 -1 -1 -1

Time complexity : O(n)

This article is contributed by Nishant_Singh(Pintu). If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

GATE CS Corner    Company Wise Coding Practice

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.

Recommended Posts:



3.1 Average Difficulty : 3.1/5.0
Based on 15 vote(s)










Writing code in comment? Please use ide.geeksforgeeks.org, generate link and share the link here.