Find next Smaller of next Greater in an array in C++

C++Server Side ProgrammingProgramming

In this problem, we are given an array arr[] consisting of n integer values. Our task is to Find the next Smaller of the next Greater in an array.

Problem Description − We will find an element greater than the current element in the array and then we will be finding the element in the array which is smaller than this greater element. And if no next smaller or next greater element exists in the array return -1.

Let’s take an example to understand the problem,

Input

arr[] = {4, 2, 8, 3, 9, 1}

Output

{3, 3, 1, 1, -1, -1}

Explanation

Array of next greater elements : {8, 8, 9, 9, -1, -1} Since 9 is the largest element of the array and 1 is the last element, they don't have the next greater element.

Array of next smaller of next greater elements : {3, 3, 1, 1, -1, -1}

Solution Approach

A simple solution to the problem is by iterating over the array and for each element of the array,

  • Find the next greater element from the array.

  • Find a smaller element than this greater element in the remaining array.

This solution to do its job but the time complexity is of the order O(n2).

A better solution to the problem can be using the stack and indexes of the elements.

We will store the index of the next greater and smaller element of the current element in the array in two arrays names nextGreater[] and nextSmaller[]. This means the array nextGreater will store the index of the next greater element of the current element. For example nextGreater[i] will have the index of next greater element which will be arr[nextGreater[i]]. And the same will be for nextSmaller[] also.

So, to access the next smallest element of the next greater element of the array. We will find the next smaller element of index at nextGreater[i]. This will give the index of our required element, i.e. the required element is arr[nextSmaller[nextGreater[i]]].

For finding the element, we will use stack data structure which will store the elements of the remaining subarray. Here is how the function will work for finding greater elements.

  • => We will traverse the array from last, i -> n-1 to 0.

  • => If the stack is not empty and the top of stack is smaller than current element -> pop S, do this until a greater element is found or the stack gets empty.

  • => If stack is empty -> there is no greater element possible, store -1, nextGreater[i] = -1.

  • => else -> next greater element is at top of stack, store the top of stack, nextGreater[i] = stack.top().

  • => push the current element into the stack, stack.push()

The same method can be used to find the next smaller element for the current element of the array. And once we have found the indexes of both. We can use these indexes to find the required element from the array.

Program to illustrate the working of our solution,

Example

 Live Demo

#include<bits/stdc++.h>
using namespace std;
void findNextGreater(int arr[], int n, int next[]) {
   stack<int> nextGreater;
   int i = n-1;
   while(i >= 0) {
      while (!nextGreater.empty() && arr[nextGreater.top()] <= arr[i] )
         nextGreater.pop();
      if (!nextGreater.empty())
         next[i] = nextGreater.top();
      else
         next[i] = -1;
      nextGreater.push(i);
      i--;
   }
}
void findNextSmaller(int arr[], int n, int next[]) {
   stack<int> nextSmaller;
   int i = n-1 ;
   while(i >= 0){
      while (!nextSmaller.empty() && arr[nextSmaller.top()] >= arr[i])
         nextSmaller.pop();
      if (!nextSmaller.empty())
         next[i] = nextSmaller.top();
      else
         next[i] = -1;
      nextSmaller.push(i);
      i -- ;
   }
}
void findNextSmallerofNextGreaterElemenetArray(int arr[], int n) {
   int nextGreaterIndex[n];
   int nextSmallerIndex[n];
   findNextGreater(arr, n, nextGreaterIndex);
   findNextSmaller(arr, n, nextSmallerIndex);
   for (int i=0; i< n; i++){
      if (nextGreaterIndex[i] != -1 && nextSmallerIndex[nextGreaterIndex[i]] != -1)
         cout<<arr[nextSmallerIndex[nextGreaterIndex[i]]]<<"\t";
      else
         cout<<"-1"<<"\t";
   }
}
int main(){
   int arr[] = {4, 2, 8, 3, 9, 1};
   int n = sizeof(arr)/sizeof(arr[0]);
   cout<<"All next smaller of next greater elements of the array are ";
   findNextSmallerofNextGreaterElemenetArray(arr, n);
   return 0;
}

Output

All next smaller of next greater elements of the array are 3 3 1 1 -1 -1
raja
Published on 13-Mar-2021 13:02:19
Advertisements