Find maximum difference between nearest left and right smaller elements in C++

C++Server Side ProgrammingProgramming

Concept

With respect of a given an array of integers, our task is to determine the maximum absolute difference between the nearest left and the right smaller element of every element in the array. It should be noted that if there is no smaller element on right side or left side of any element then we accept zero as the smaller element. Here,for example for the leftmost element, the nearest smaller element on the left side is set as 0. In the same way, for rightmost elements, the smaller element on the right side is set as 0.

Input

arr[] = {3, 2, 9}

Output

2

Left smaller LS[] {0, 0, 2}

Right smaller RS[] {2, 0, 0}

Maximum Diff of abs(LS[i] - RS[i]) = 2 - 0 = 2

Input

arr[] = {3, 5, 9, 8, 8, 10, 4}

Output

4

Left smaller LS[] = {0, 3, 5, 5, 5, 8, 3}

Right smaller RS[] = {0, 4, 8, 4, 4, 4, 0}

Maximum Diff of abs(LS[i] - RS[i]) = 8 - 4 = 4

Method

We apply a simple solution where our task is to find the nearest left and right smaller elements for every element and after that update the maximum difference between left and right smaller element, this consumes O(n^2) time.

Again we implement an efficient solution which consumes O(n) time. Here, we implement a stack. Here, the interesting part here is we calculate both left smaller and right smaller using same function.

Assume input array be 'Array[]' and size of array be 'n'

Determine all smaller element on left side

• Build a new empty stack S and an array LS[]
• Now for every element 'Array[i]' in the input Array[],where 'i' goes from 0 to n-1.
• while S is nonempty and the top element of S is greater than or equal to 'Array[i]': pop S
• if S is empty: 'Array[i]' has no preceding smaller value LS[i] = 0
• else: the nearest smaller value to 'Array[i]' is top of stack LS[i] = S.top()
• push 'Array[i]' onto S
• Determine all smaller element on right side
• At first reverse array Array[]. Now after reversing the array, right smaller become left smaller.
• Build an array RRS[] and repeat steps 1 and 2 to fill RRS (in-place of LS).
• We initialize result as -1 and do following for every element Array[i]. With respect of the reversed array right smaller for Array[i] is stored at RRS[n-i-1] return result = max(result, LS[i]-RRS[n-i-1])

Example

Live Demo

// C++ program to find the difference b/w left and
// right smaller element of every element in array
#include<bits/stdc++.h>
using namespace std;
// Shows function to fill left smaller element for every
// element of Array[0..n1-1]. These values are filled
// in SE1[0..n1-1]
void leftSmaller(int Array[], int n1, int SE1[]){
// Build an empty stack
stack<int>S1;
// Visit all array elements
// Calculate nearest smaller elements of every element
for (int i=0; i<n1; i++){
// Used to keep removing top element from S1 while the top
// element is greater than or equal to Array[i]
while (!S1.empty() && S1.top() >= Array[i])
S1.pop();
// Used to store the smaller element of current element
if (!S1.empty())
SE1[i] = S1.top();
// It has been seen that if all elements in S were greater than Array[i]
else
SE1[i] = 0;
// Used to push this element
S1.push(Array[i]);
}
}
// Shows function returns maximum difference b/w Left &
// right smaller element
int findMaxDiff(int Array[], int n1){
int LS1[n1]; // To store left smaller elements
// find left smaller element of every element
leftSmaller(Array, n1, LS1);
// Determine right smaller element of every element
// first reverse the array and do the same process
int RRS1[n1]; // Used to store right smaller elements in
// reverse array
reverse(Array, Array + n1);
leftSmaller(Array, n1, RRS1);
// Determine maximum absolute difference b/w LS1 & RRS1
// In the reversed array right smaller for Array[i] is
// stored at RRS1[n1-i-1]
int result1 = -1;
for (int i=0 ; i< n1 ; i++)
result1 = max(result1, abs(LS1[i] - RRS1[n1-1-i]));
// return maximum difference between LS1 & RRS1
return result1;
}
// Driver program
int main(){
int Array[] = {3, 5, 9, 8, 8, 10, 4};
int n = sizeof(Array)/sizeof(Array[0]);
cout << "Maximum diff : "
<< findMaxDiff(Array, n) << endl;
return 0;
}

Output

Maximum diff : 4
Published on 24-Jul-2020 15:34:03