Find maximum difference between nearest left and right smaller elements

06 Jul, 2022
Given an array of integers, the task is to find the maximum absolute difference between the nearest left and the right smaller element of every element in the array. 
Note: If there is no smaller element on right side or left side of any element then we take zero as the smaller element. For example for the leftmost element, the nearest smaller element on the left side is considered as 0. Similarly, for rightmost elements, the smaller element on the right side is considered as 0.
Examples: 
Input : arr[] = {2, 1, 8}
Output : 1
Left smaller  LS[] {0, 0, 1}
Right smaller RS[] {1, 0, 0}
Maximum Diff of abs(LS[i] - RS[i]) = 1 

Input  : arr[] = {2, 4, 8, 7, 7, 9, 3}
Output : 4
Left smaller   LS[] = {0, 2, 4, 4, 4, 7, 2}
Right smaller  RS[] = {0, 3, 7, 3, 3, 3, 0}
Maximum Diff of abs(LS[i] - RS[i]) = 7 - 3 = 4 

Input : arr[] = {5, 1, 9, 2, 5, 1, 7}
Output : 1
A simple solution is to find the nearest left and right smaller elements for every element and then update the maximum difference between left and right smaller element, this takes O(n^2) time. 
An efficient solution takes O(n) time. We use a stack. The idea is based on the approach discussed in next greater element article. The interesting part here is we compute both left smaller and right smaller using same function. 
Let input array be 'arr[]' and size of array be 'n'

Find all smaller element on left side
     1. Create a new empty stack S and an array LS[]
     2. For every element 'arr[i]' in the input arr[],
          where 'i' goes from 0 to n-1.
        a) while S is nonempty and the top element of 
           S is greater than or equal to 'arr[i]':
           pop S
    
        b) if S is empty:
           'arr[i]' has no preceding smaller value 
            LS[i] = 0 
            
        c) else:
            the nearest smaller value to 'arr[i]' is top
            of stack
              LS[i] = s.top()

        d) push 'arr[i]' onto S   

Find all smaller element on right side
     3. First reverse array arr[]. After reversing the array, 
        right smaller become left smaller.
     4. Create an array RRS[] and repeat steps  1 and 2 to 
        fill RRS (in-place of LS).
         
5. Initialize result as -1 and do following for every element
   arr[i]. In the reversed array right smaller for arr[i] is
   stored at RRS[n-i-1]
      return result = max(result, LS[i]-RRS[n-i-1])
Below is implementation of above idea  
C++
Java
Python3
C#
PHP
Javascript
// 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; // Function to fill left smaller element for every// element of arr[0..n-1]. These values are filled// in SE[0..n-1]void leftSmaller(int arr[], int n, int SE[]){    // Create an empty stack    stack<int>S;     // Traverse all array elements    // compute nearest smaller elements of every element    for (int i=0; i<n; i++)    {        // Keep removing top element from S while the top        // element is greater than or equal to arr[i]        while (!S.empty() && S.top() >= arr[i])            S.pop();         // Store the smaller element of current element        if (!S.empty())            SE[i] = S.top();         // If all elements in S were greater than arr[i]        else            SE[i] = 0;         // Push this element        S.push(arr[i]);    }} // Function returns maximum difference b/w Left &// right smaller elementint findMaxDiff(int arr[], int n){    int LS[n]; // To store left smaller elements     // find left smaller element of every element    leftSmaller(arr, n, LS);     // find right smaller element of every element    // first reverse the array and do the same process    int RRS[n]; // To store right smaller elements in                // reverse array    reverse(arr, arr + n);    leftSmaller(arr, n, RRS);     // find maximum absolute difference b/w LS & RRS    // In the reversed array right smaller for arr[i] is    // stored at RRS[n-i-1]    int result = -1;    for (int i=0 ; i< n ; i++)        result = max(result, abs(LS[i] - RRS[n-1-i]));     // return maximum difference b/w LS & RRS    return result;} // Driver programint main(){    int arr[] = {2, 4, 8, 7, 7, 9, 3};    int n = sizeof(arr)/sizeof(arr[0]);    cout << "Maximum diff : "        << findMaxDiff(arr, n) << endl;    return 0;}
// Java program to find the difference b/w left and// right smaller element of every element in arrayimport java.util.*; class GFG{     // Function to fill left smaller element for every    // element of arr[0..n-1]. These values are filled    // in SE[0..n-1]    static void leftSmaller(int arr[], int n, int SE[])    {        // Create an empty stack        Stack<Integer> S = new Stack<>();         // Traverse all array elements        // compute nearest smaller elements of every element        for (int i = 0; i < n; i++)        {            // Keep removing top element from S while the top            // element is greater than or equal to arr[i]            while (!S.empty() && S.peek() >= arr[i])            {                S.pop();            }             // Store the smaller element of current element            if (!S.empty())            {                SE[i] = S.peek();            }            // If all elements in S were greater than arr[i]            else            {                SE[i] = 0;            }             // Push this element            S.push(arr[i]);        }    }     // Function returns maximum difference b/w Left &    // right smaller element    static int findMaxDiff(int arr[], int n)    {        int[] LS = new int[n]; // To store left smaller elements         // find left smaller element of every element        leftSmaller(arr, n, LS);         // find right smaller element of every element        // first reverse the array and do the same process        int[] RRS = new int[n]; // To store right smaller elements in                 // reverse array        reverse(arr);        leftSmaller(arr, n, RRS);         // find maximum absolute difference b/w LS & RRS        // In the reversed array right smaller for arr[i] is        // stored at RRS[n-i-1]        int result = -1;        for (int i = 0; i < n; i++)        {            result = Math.max(result, Math.abs(LS[i] - RRS[n - 1 - i]));        }         // return maximum difference b/w LS & RRS        return result;    }     static void reverse(int a[])    {        int i, k, n = a.length;        int t;        for (i = 0; i < n / 2; i++)        {            t = a[i];            a[i] = a[n - i - 1];            a[n - i - 1] = t;        }    }         // Driver code    public static void main(String args[])    {        int arr[] = {2, 4, 8, 7, 7, 9, 3};        int n = arr.length;        System.out.println("Maximum diff : "                + findMaxDiff(arr, n));    }} // This code is contributed by Princi Singh
# Python program to find the difference b/w left and# right smaller element of every element in the array # Function to fill left smaller element for every# element of arr[0..n-1]. These values are filled# in SE[0..n-1]def leftsmaller(arr, n, SE):     # create an empty stack    sta = []    # Traverse all array elements    # compute nearest smaller elements of every element    for i in range(n):                 # Keep removing top element from S while the top        # element is greater than or equal to arr[i]        while(sta != [] and sta[len(sta)-1] >= arr[i]):            sta.pop()         # Store the smaller element of current element        if(sta != []):            SE[i]=sta[len(sta)-1]        # If all elements in S were greater than arr[i]        else:            SE[i]=0         # push this element        sta.append(arr[i]) # Function returns maximum difference b/w  Left  &# right smaller elementdef findMaxDiff(arr, n):    ls=[0]*n # to store left smaller elements    rs=[0]*n # to store right smaller elements     # find left smaller elements of every element    leftsmaller(arr, n, ls)         # find right smaller element of every element    # by sending reverse of array    leftsmaller(arr[::-1], n, rs)     # find maximum absolute difference b/w LS  & RRS    # In the reversed array right smaller for arr[i] is    # stored at RRS[n-i-1]    res = -1    for i in range(n):        res = max(res, abs(ls[i] - rs[n-1-i]))    # return maximum difference b/w LS  & RRS    return res      # Driver Programif __name__=='__main__':    arr = [2, 4, 8, 7, 7, 9, 3]    print "Maximum Diff :", findMaxDiff(arr, len(arr))     #Contributed By: Harshit Sidhwa
// C# program to find the difference b/w left and// right smaller element of every element in arrayusing System;using System.Collections.Generic; class GFG{     // Function to fill left smaller element for every    // element of arr[0..n-1]. These values are filled    // in SE[0..n-1]    static void leftSmaller(int []arr, int n, int []SE)    {        // Create an empty stack        Stack<int> S = new Stack<int>();         // Traverse all array elements        // compute nearest smaller elements of every element        for (int i = 0; i < n; i++)        {            // Keep removing top element from S while the top            // element is greater than or equal to arr[i]            while (S.Count != 0 && S.Peek() >= arr[i])            {                S.Pop();            }             // Store the smaller element of current element            if (S.Count != 0)            {                SE[i] = S.Peek();            }                         // If all elements in S were greater than arr[i]            else            {                SE[i] = 0;            }             // Push this element            S.Push(arr[i]);        }    }     // Function returns maximum difference b/w Left &    // right smaller element    static int findMaxDiff(int []arr, int n)    {        int[] LS = new int[n]; // To store left smaller elements         // find left smaller element of every element        leftSmaller(arr, n, LS);         // find right smaller element of every element        // first reverse the array and do the same process        int[] RRS = new int[n]; // To store right smaller elements in                                // reverse array        reverse(arr);        leftSmaller(arr, n, RRS);         // find maximum absolute difference b/w LS & RRS        // In the reversed array right smaller for arr[i] is        // stored at RRS[n-i-1]        int result = -1;        for (int i = 0; i < n; i++)        {            result = Math.Max(result, Math.Abs(LS[i] -                                               RRS[n - 1 - i]));        }         // return maximum difference b/w LS & RRS        return result;    }     static void reverse(int[] a)    {        int i, k, n = a.Length;        int t;        for (i = 0; i < n / 2; i++)        {            t = a[i];            a[i] = a[n - i - 1];            a[n - i - 1] = t;        }    }         // Driver code    public static void Main(String []args)    {        int []arr = {2, 4, 8, 7, 7, 9, 3};        int n = arr.Length;        Console.WriteLine("Maximum diff : " +                           findMaxDiff(arr, n));    }} // This code is contributed by 29AjayKumar
<?php// Function to fill left smaller// element for every element of// arr[0..n-1]. These values are// filled in SE[0..n-1]function leftSmaller(&$arr, $n, &$SE){    $S = array();     // Traverse all array elements    // compute nearest smaller    // elements of every element    for ($i = 0; $i < $n; $i++)    {        // Keep removing top element        // from S while the top element        // is greater than or equal to arr[i]        while (!empty($S) && max($S) >= $arr[$i])            array_pop($S);         // Store the smaller element        // of current element        if (!empty($S))            $SE[$i] = max($S);         // If all elements in S were        // greater than arr[i]        else            $SE[$i] = 0;         // Push this element        array_push($S, $arr[$i]);    }} // Function returns maximum// difference b/w Left &// right smaller elementfunction findMaxDiff(&$arr, $n){    // To store left smaller elements    $LS = array_fill(0, $n, NULL);     // find left smaller element    // of every element    leftSmaller($arr, $n, $LS);     // find right smaller element    // of every element first reverse    // the array and do the same process         // To store right smaller    // elements in reverse array    $RRS = array_fill(0, $n, NULL);                     $k = 0;    for($i = $n - 1; $i >= 0; $i--)        $x[$k++] = $arr[$i];    leftSmaller($x, $n, $RRS);     // find maximum absolute difference    // b/w LS & RRS. In the reversed    // array right smaller for arr[i]    // is stored at RRS[n-i-1]    $result = -1;    for ($i = 0 ; $i < $n ; $i++)        $result = max($result, abs($LS[$i] -                      $RRS[$n - 1 - $i]));     // return maximum difference    // b/w LS & RRS    return $result;} // Driver Code$arr = array(2, 4, 8, 7, 7, 9, 3);$n = sizeof($arr);echo "Maximum diff : " .      findMaxDiff($arr, $n) . "\n"; // This code is contributed// by ChitraNayal?>
<script>// Javascript program to find the difference b/w left and// right smaller element of every element in array         // Function to fill left smaller element for every    // element of arr[0..n-1]. These values are filled    // in SE[0..n-1]    function leftSmaller(arr,n,SE)    {        // Create an empty stack        let S=[]                 // Traverse all array elements        // compute nearest smaller elements of every element        for (let i = 0; i < n; i++)        {            // Keep removing top element from S while the top            // element is greater than or equal to arr[i]            while (S.length!=0 && S[S.length-1] >= arr[i])            {                S.pop();            }               // Store the smaller element of current element            if (S.length!=0)            {                SE[i] = S[S.length-1];            }            // If all elements in S were greater than arr[i]            else            {                SE[i] = 0;            }               // Push this element            S.push(arr[i]);        }             }         // Function returns maximum difference b/w Left &    // right smaller element    function findMaxDiff(arr,n)    {        // To store left smaller elements        let LS = new Array(n);        for(let i=0;i<n;i++)        {            LS[i]=0;        }        // find left smaller element of every element        leftSmaller(arr, n, LS);           // find right smaller element of every element        // first reverse the array and do the same process        let RRS = new Array(n); // To store right smaller elements in        for(let i=0;i<n;i++)        {            RRS[i]=0;        }                   // reverse array        reverse(arr);        leftSmaller(arr, n, RRS);           // find maximum absolute difference b/w LS & RRS        // In the reversed array right smaller for arr[i] is        // stored at RRS[n-i-1]        let result = -1;        for (let i = 0; i < n; i++)        {            result = Math.max(result, Math.abs(LS[i] - RRS[n - 1 - i]));        }           // return maximum difference b/w LS & RRS        return result;    }         function reverse(a)    {        let i, k, n = a.length;        let t;        for (i = 0; i < Math.floor(n / 2); i++)        {            t = a[i];            a[i] = a[n - i - 1];            a[n - i - 1] = t;        }    }         // Driver code    let arr=[2, 4, 8, 7, 7, 9, 3];    let n = arr.length;    document.write("Maximum diff : "                + findMaxDiff(arr, n));         // This code is contributed by rag2127</script>
Maximum diff : 4

Time complexity: O(n)Auxiliary Space: 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 write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks. 
ukasp
princi singh
29AjayKumar
rag2127
sweetyty
anandkumarshivam2266
hardikkoriintern
Arrays
Stack
Arrays
Stack
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.