📌  相关文章
📜  找到最近的左右较小元素之间的最大差异

📅  最后修改于: 2022-05-13 01:57:09.126000             🧑  作者: Mango

找到最近的左右较小元素之间的最大差异

给定一个整数数组,任务是找到数组中每个元素的最接近的左侧和右侧较小元素之间的最大绝对差。

注意:如果任何元素的右侧或左侧都没有较小的元素,则我们将零作为较小的元素。例如对于最左边的元素,左边最近的较小元素被认为是 0。同样,对于最右边的元素,右边的较小元素被认为是 0。

例子:

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

一个简单的解决方案是为每个元素找到最近的左右较小元素,然后更新左右较小元素之间的最大差异,这需要 O(n^2) 时间。

一个有效的解决方案需要 O(n) 时间。我们使用堆栈。这个想法是基于在下一个更大的元素文章中讨论的方法。这里有趣的部分是我们使用相同的函数计算左小和右小。

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])

以下是上述想法的实现

C++
// C++ program to find the difference b/w left and
// right smaller element of every element in array
#include
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
    stackS;
 
    // Traverse all array elements
    // compute nearest smaller elements of every element
    for (int i=0; i= 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 element
int 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 program
int 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
// Java program to find the difference b/w left and
// right smaller element of every element in array
import 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 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


Python3
# 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 element
def 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 Program
if __name__=='__main__':
    arr = [2, 4, 8, 7, 7, 9, 3]
    print "Maximum Diff :", findMaxDiff(arr, len(arr))
     
#Contributed By: Harshit Sidhwa


C#
// C# program to find the difference b/w left and
// right smaller element of every element in array
using 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 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.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
= $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 element
function 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
?>


Javascript


输出:

Maximum Diff  : 4

时间复杂度: O(n)