Encuentre el máximo del mínimo para cada tamaño de ventana en una array dada

Dada una array de enteros de tamaño n, encuentre el máximo de los mínimos de cada tamaño de ventana en la array. Tenga en cuenta que el tamaño de la ventana varía de 1 a n.

Ejemplo:

 
Entrada: arr[] = {10, 20, 30, 50, 10, 70, 30} 
Salida: 70, 30, 20, 10, 10, 10, 10
El primer elemento en la salida indica el máximo de los mínimos de todas las 
ventanas de tamaño 1. 
Los mínimos de ventanas de tamaño 1 son {10}, {20}, {30}, {50}, {10}, 
{70} y {30}. El máximo de estos mínimos es 70
El segundo elemento en la salida indica el máximo de mínimos de todas las 
ventanas de tamaño 2.  Los mínimos de
ventanas de tamaño 2 son {10}, {20}, {30}, {10}, {10} y 
{30}. El máximo de estos mínimos es 30.
El tercer elemento en la salida indica el máximo de mínimos de todas las 
ventanas de tamaño 3.  Los mínimos de
ventanas de tamaño 3 son {10}, {20}, {10}, {10} y {10} . 
El máximo de estos mínimos es 20
De manera similar, se calculan otros elementos de la salida. 

Solución ingenua : fuerza bruta. 

Enfoque: un enfoque simple de fuerza bruta para resolver este problema puede ser generar todas las ventanas posibles de una longitud particular, digamos ‘L’ y encontrar el elemento mínimo en todas esas ventanas. Luego encuentre el máximo de todos esos elementos y guárdelo. Ahora la longitud de la ventana es 1<=L<=N. Así que tenemos que generar todas las ventanas posibles de tamaño ‘1’ a ‘N’ y para generar cada una de esas ventanas tenemos que marcar los puntos finales de esa ventana. Entonces, para eso, tenemos que usar un bucle anidado para fijar el punto inicial y final de la ventana, respectivamente. Por lo tanto, habrá un uso de bucle anidado triple en el enfoque de fuerza bruta principalmente para fijar la longitud de la ventana, el punto de inicio y el punto final.

C++

// A naive method to find maximum of
// minimum of all windows of different
// sizes
#include <bits/stdc++.h>
using namespace std;
 
void printMaxOfMin(int arr[], int n)
{
    // Consider all windows of different
    // sizes starting from size 1
    for (int k = 1; k <= n; k++) {
        // Initialize max of min for
        // current window size k
        int maxOfMin = INT_MIN;
 
        // Traverse through all windows
        // of current size k
        for (int i = 0; i <= n - k; i++) {
            // Find minimum of current window
            int min = arr[i];
            for (int j = 1; j < k; j++) {
                if (arr[i + j] < min)
                    min = arr[i + j];
            }
 
            // Update maxOfMin if required
            if (min > maxOfMin)
                maxOfMin = min;
        }
 
        // Print max of min for current
        // window size
        cout << maxOfMin << " ";
    }
}
 
// Driver program
int main()
{
    int arr[] = { 10, 20, 30, 50, 10, 70, 30 };
    int n = sizeof(arr) / sizeof(arr[0]);
    printMaxOfMin(arr, n);
    return 0;
}

Java

// A naive method to find maximum of
// minimum of all windows of different sizes
 
class Test {
    static int arr[] = { 10, 20, 30, 50, 10, 70, 30 };
 
    static void printMaxOfMin(int n)
    {
        // Consider all windows of different
        // sizes starting from size 1
        for (int k = 1; k <= n; k++) {
            // Initialize max of min for current
            // window size k
            int maxOfMin = Integer.MIN_VALUE;
 
            // Traverse through all windows of
            // current size k
            for (int i = 0; i <= n - k; i++) {
                // Find minimum of current window
                int min = arr[i];
                for (int j = 1; j < k; j++) {
                    if (arr[i + j] < min)
                        min = arr[i + j];
                }
 
                // Update maxOfMin if required
                if (min > maxOfMin)
                    maxOfMin = min;
            }
 
            // Print max of min for current
            // window size
            System.out.print(maxOfMin + " ");
        }
    }
 
    // Driver method
    public static void main(String[] args)
    {
        printMaxOfMin(arr.length);
    }
}

Python3

# A naive method to find maximum of
# minimum of all windows of different sizes
INT_MIN = -1000000
def printMaxOfMin(arr, n):
     
    # Consider all windows of different
    # sizes starting from size 1
    for k in range(1, n + 1):
         
        # Initialize max of min for
        # current window size k
        maxOfMin = INT_MIN;
 
        # Traverse through all windows
        # of current size k
        for i in range(n - k + 1):
             
            # Find minimum of current window
            min = arr[i]
            for j in range(k):
                if (arr[i + j] < min):
                    min = arr[i + j]
 
            # Update maxOfMin if required
            if (min > maxOfMin):
                maxOfMin = min
                 
        # Print max of min for current window size
        print(maxOfMin, end = " ")
 
# Driver Code
arr = [10, 20, 30, 50, 10, 70, 30]
n = len(arr)
printMaxOfMin(arr, n)
 
# This code is contributed by sahilshelangia

C#

// C# program using Naive approach to find
// maximum of minimum of all windows of
// different sizes
using System;
 
class GFG{
     
    static int []arr = {10, 20, 30, 50, 10, 70, 30};
     
    // Function to print maximum of minimum
    static void printMaxOfMin(int n)
    {
         
        // Consider all windows of different
        // sizes starting from size 1
        for (int k = 1; k <= n; k++)
        {
             
            // Initialize max of min for
            // current window size k
            int maxOfMin = int.MinValue;
     
            // Traverse through all windows
            // of current size k
            for (int i = 0; i <= n - k; i++)
            {
                 
                // Find minimum of current window
                int min = arr[i];
                for (int j = 1; j < k; j++)
                {
                    if (arr[i + j] < min)
                        min = arr[i + j];
                }
     
                // Update maxOfMin if required
                if (min > maxOfMin)
                    maxOfMin = min;
            }
     
            // Print max of min for current window size
            Console.Write(maxOfMin + " ");
        }
    }
     
    // Driver Code
    public static void Main()
    {
        printMaxOfMin(arr.Length);
    }
}
 
// This code is contributed by Sam007.

PHP

<?php
// PHP program to find maximum of
// minimum of all windows of
// different sizes
 
// Method to find maximum of
// minimum of all windows of
// different sizes
function printMaxOfMin($arr, $n)
{
     
    // Consider all windows of
    // different sizes starting
    // from size 1
    for($k = 1; $k <= $n; $k++)
    {
         
        // Initialize max of min for
        // current window size k
        $maxOfMin = PHP_INT_MIN;
 
        // Traverse through all windows
        // of current size k
        for ($i = 0; $i <= $n-$k; $i++)
        {
             
            // Find minimum of current window
            $min = $arr[$i];
            for ($j = 1; $j < $k; $j++)
            {
                if ($arr[$i + $j] < $min)
                    $min = $arr[$i + $j];
            }
 
            // Update maxOfMin
            // if required
            if ($min > $maxOfMin)
            $maxOfMin = $min;
        }
 
        // Print max of min for
        // current window size
        echo $maxOfMin , " ";
    }
}
 
    // Driver Code
    $arr= array(10, 20, 30, 50, 10, 70, 30);
    $n = sizeof($arr);
    printMaxOfMin($arr, $n);
 
// This code is contributed by nitin mittal.
?>

Javascript

<script>
 
// A naive method to find maximum of
// minimum of all windows of different sizes
 
 
    var arr = [ 10, 20, 30, 50, 10, 70, 30 ];
 
    function printMaxOfMin(n) {
        // Consider all windows of different
        // sizes starting from size 1
        for (k = 1; k <= n; k++) {
            // Initialize max of min for current
            // window size k
            var maxOfMin = Number.MIN_VALUE;
 
            // Traverse through all windows of
            // current size k
            for (i = 0; i <= n - k; i++) {
                // Find minimum of current window
                var min = arr[i];
                for (j = 1; j < k; j++) {
                    if (arr[i + j] < min)
                        min = arr[i + j];
                }
 
                // Update maxOfMin if required
                if (min > maxOfMin)
                    maxOfMin = min;
            }
 
            // Print max of min for current
            // window size
            document.write(maxOfMin + " ");
        }
    }
 
    // Driver method
     
        printMaxOfMin(arr.length);
 
// This code contributed by aashish1995
</script>
Producción

70 30 20 10 10 10 10 

Análisis de Complejidad:  

  • Complejidad Temporal: O(n 3 ). 
    Como hay un uso de bucle anidado triple en este enfoque.
  • Espacio auxiliar: O(1) 
    Dado que no se ha utilizado ninguna estructura de datos adicional para almacenar los valores.

Solución eficiente : 

Podemos resolver este problema en tiempo O(n). La idea es utilizar espacio extra. A continuación se detallan los pasos.

Paso 1: 

  • Encuentre índices del siguiente menor y el anterior menor para cada elemento. El siguiente más pequeño es el elemento más pequeño más cercano en el lado derecho de arr[i]. De manera similar, un elemento más pequeño anterior es el elemento más pequeño más cercano en el lado izquierdo de arr[i]. 
  • Si no hay ningún elemento más pequeño en el lado derecho, entonces el siguiente más pequeño es n. Si no hay menor en el lado izquierdo, entonces el menor anterior es -1.
  • Para la entrada {10, 20, 30, 50, 10, 70, 30}, la array de índices del siguiente menor es {7, 4, 4, 4, 7, 6, 7}. 
  • Para la entrada {10, 20, 30, 50, 10, 70, 30}, la array de índices de menor anterior es {-1, 0, 1, 2, -1, 4, 4}
  • Este paso se puede realizar en tiempo O(n) usando el enfoque discutido en el siguiente elemento mayor .

Paso 2: 

Una vez que tenemos índices de siguiente y anterior más pequeños, sabemos que arr[i] es un mínimo de una ventana de longitud “derecha[i] – izquierda[i] – 1”. Las longitudes de las ventanas para las que los elementos son mínimos son {7, 3, 2, 1, 7, 1, 2}. Esta array indica que el primer elemento es mínimo en la ventana de tamaño 7, el segundo elemento es mínimo en la ventana de tamaño 3, y así sucesivamente.

Cree una array auxiliar ans[n+1] para almacenar el resultado. Los valores en ans[] se pueden completar iterando a través de right[] y left[] 

    for (int i=0; i < n; i++)
    {
        // length of the interval
        int len = right[i] - left[i] - 1;

        // arr[i] is a possible answer for
        // this length len interval
        ans[len] = max(ans[len], arr[i]);
    }

Obtenemos la array ans[] como {0, 70, 30, 20, 0, 0, 0, 10}. Tenga en cuenta que ans[0] o respuesta para la longitud 0 es inútil.

Paso 3: 

Algunas entradas en ans[] son ​​0 y aún no se han completado. Por ejemplo, sabemos que el máximo del mínimo para las longitudes 1, 2, 3 y 7 son 70, 30, 20 y 10 respectivamente, pero no sabemos lo mismo para las longitudes 4, 5 y 6. 

A continuación se presentan algunas observaciones importantes para completar las entradas restantes

  1. El resultado para la longitud i, es decir, ans[i] siempre sería mayor o igual que el resultado para la longitud i+1, es decir, ans[i+1]. 
  2. Si ans[i] no está lleno, significa que no hay ningún elemento directo que sea mínimo de longitud i y, por lo tanto, el elemento de longitud ans[i+1], o ans[i+2], y así sucesivamente es lo mismo que ans [i] 
    Así que llenamos el resto de las entradas usando el siguiente bucle. 
    for (int i=n-1; i>=1; i--)
        ans[i] = max(ans[i], ans[i+1]);

A continuación se muestra la implementación del algoritmo anterior.  

C++

// An efficient C++ program to find
// maximum of all minimums of
// windows of different sizes
#include <iostream>
#include<stack>
using namespace std;
 
void printMaxOfMin(int arr[], int n)
{
// Used to find previous and next smaller
    stack<int> s;
 
    // Arrays to store previous and next smaller
    int left[n+1]; 
    int right[n+1];
 
    // Initialize elements of left[] and right[]
    for (int i=0; i<n; i++)
    {
        left[i] = -1;
        right[i] = n;
    }
 
    // Fill elements of left[] using logic discussed on
    // https://www.geeksforgeeks.org/next-greater-element/
    for (int i=0; i<n; i++)
    {
        while (!s.empty() && arr[s.top()] >= arr[i])
            s.pop();
 
        if (!s.empty())
            left[i] = s.top();
 
        s.push(i);
    }
 
    // Empty the stack as stack is
// going to be used for right[]
    while (!s.empty())
        s.pop();
 
    // Fill elements of right[] using same logic
    for (int i = n-1 ; i>=0 ; i-- )
    {
        while (!s.empty() && arr[s.top()] >= arr[i])
            s.pop();
 
        if(!s.empty())
            right[i] = s.top();
 
        s.push(i);
    }
 
    // Create and initialize answer array
    int ans[n+1];
    for (int i=0; i<=n; i++)
        ans[i] = 0;
 
    // Fill answer array by comparing minimums of all
    // lengths computed using left[] and right[]
    for (int i=0; i<n; i++)
    {
        // length of the interval
        int len = right[i] - left[i] - 1;
 
        // arr[i] is a possible answer for this length
        // 'len' interval, check if arr[i] is more than
        // max for 'len'
        ans[len] = max(ans[len], arr[i]);
    }
 
    // Some entries in ans[] may not be filled yet. Fill
    // them by taking values from right side of ans[]
    for (int i=n-1; i>=1; i--)
        ans[i] = max(ans[i], ans[i+1]);
 
    // Print the result
    for (int i=1; i<=n; i++)
        cout << ans[i] << " ";
}
 
// Driver program
int main()
{
    int arr[] = {10, 20, 30, 50, 10, 70, 30};
    int n = sizeof(arr)/sizeof(arr[0]);
    printMaxOfMin(arr, n);
    return 0;
}

Java

// An efficient Java program to find
// maximum of all minimums of
// windows of different size
 
import java.util.Stack;
 
class Test
{
    static int arr[] = {10, 20, 30, 50, 10, 70, 30};
     
    static void printMaxOfMin(int n)
    {
        // Used to find previous and next smaller
        Stack<Integer> s = new Stack<>();
      
        // Arrays to store previous and next smaller
        int left[] = new int[n+1]; 
        int right[]  = new int[n+1];
      
        // Initialize elements of left[] and right[]
        for (int i=0; i<n; i++)
        {
            left[i] = -1;
            right[i] = n;
        }
      
        // Fill elements of left[] using logic discussed on
        // https://www.geeksforgeeks.org/next-greater-element/
        for (int i=0; i<n; i++)
        {
            while (!s.empty() && arr[s.peek()] >= arr[i])
                s.pop();
      
            if (!s.empty())
                left[i] = s.peek();
      
            s.push(i);
        }
      
        // Empty the stack as stack is
// going to be used for right[]
        while (!s.empty())
            s.pop();
      
        // Fill elements of right[] using same logic
        for (int i = n-1 ; i>=0 ; i-- )
        {
            while (!s.empty() && arr[s.peek()] >= arr[i])
                s.pop();
      
            if(!s.empty())
                right[i] = s.peek();
      
            s.push(i);
        }
      
        // Create and initialize answer array
        int ans[] = new int[n+1];
        for (int i=0; i<=n; i++)
            ans[i] = 0;
      
        // Fill answer array by comparing minimums of all
        // lengths computed using left[] and right[]
        for (int i=0; i<n; i++)
        {
            // length of the interval
            int len = right[i] - left[i] - 1;
      
            // arr[i] is a possible answer for this length
            // 'len' interval, check if arr[i] is more than
            // max for 'len'
            ans[len] = Math.max(ans[len], arr[i]);
        }
      
        // Some entries in ans[] may not be filled yet. Fill
        // them by taking values from right side of ans[]
        for (int i=n-1; i>=1; i--)
            ans[i] = Math.max(ans[i], ans[i+1]);
      
        // Print the result
        for (int i=1; i<=n; i++)
            System.out.print(ans[i] + " ");
    }
     
    // Driver method
    public static void main(String[] args)
    {
        printMaxOfMin(arr.length);
    }
}

Python3

# An efficient Python3 program to find
# maximum of all minimums of windows of
# different sizes
 
def printMaxOfMin(arr, n):
     
    s = [] # Used to find previous
           # and next smaller
 
    # Arrays to store previous and next
    # smaller. Initialize elements of
    # left[] and right[]
    left = [-1] * (n + 1)
    right = [n] * (n + 1)
 
    # Fill elements of left[] using logic discussed on
    # https:#www.geeksforgeeks.org/next-greater-element
    for i in range(n):
        while (len(s) != 0 and
               arr[s[-1]] >= arr[i]):
            s.pop()
 
        if (len(s) != 0):
            left[i] = s[-1]
 
        s.append(i)
 
    # Empty the stack as stack is going
    # to be used for right[]
    while (len(s) != 0):
        s.pop()
 
    # Fill elements of right[] using same logic
    for i in range(n - 1, -1, -1):
        while (len(s) != 0 and arr[s[-1]] >= arr[i]):
            s.pop()
 
        if(len(s) != 0):
            right[i] = s[-1]
 
        s.append(i)
 
    # Create and initialize answer array
    ans = [0] * (n + 1)
    for i in range(n + 1):
        ans[i] = 0
 
    # Fill answer array by comparing minimums
    # of all. Lengths computed using left[]
    # and right[]
    for i in range(n):
         
        # Length of the interval
        Len = right[i] - left[i] - 1
 
        # arr[i] is a possible answer for this
        #  Length 'Len' interval, check if arr[i]
        # is more than max for 'Len'
        ans[Len] = max(ans[Len], arr[i])
 
    # Some entries in ans[] may not be filled
    # yet. Fill them by taking values from
    # right side of ans[]
    for i in range(n - 1, 0, -1):
        ans[i] = max(ans[i], ans[i + 1])
 
    # Print the result
    for i in range(1, n + 1):
        print(ans[i], end = " ")
 
# Driver Code
if __name__ == '__main__':
 
    arr = [10, 20, 30, 50, 10, 70, 30]
    n = len(arr)
    printMaxOfMin(arr, n)
 
# This code is contributed by PranchalK

C#

// An efficient C# program to find maximum
// of all minimums of windows of different size
using System;
using System.Collections.Generic;
 
class GFG
{
public static int[] arr = new int[] {10, 20, 30, 50,
                                     10, 70, 30};
 
public static void printMaxOfMin(int n)
{
    // Used to find previous and next smaller
    Stack<int> s = new Stack<int>();
 
    // Arrays to store previous
    // and next smaller
    int[] left = new int[n + 1];
    int[] right = new int[n + 1];
 
    // Initialize elements of left[]
    // and right[]
    for (int i = 0; i < n; i++)
    {
        left[i] = -1;
        right[i] = n;
    }
 
    // Fill elements of left[] using logic discussed on
    // https://www.geeksforgeeks.org/next-greater-element/
    for (int i = 0; i < n; i++)
    {
        while (s.Count > 0 &&
               arr[s.Peek()] >= arr[i])
        {
            s.Pop();
        }
 
        if (s.Count > 0)
        {
            left[i] = s.Peek();
        }
 
        s.Push(i);
    }
 
    // Empty the stack as stack is going
    // to be used for right[]
    while (s.Count > 0)
    {
        s.Pop();
    }
 
    // Fill elements of right[] using
    // same logic
    for (int i = n - 1 ; i >= 0 ; i--)
    {
        while (s.Count > 0 &&
               arr[s.Peek()] >= arr[i])
        {
            s.Pop();
        }
 
        if (s.Count > 0)
        {
            right[i] = s.Peek();
        }
 
        s.Push(i);
    }
 
    // Create and initialize answer array
    int[] ans = new int[n + 1];
    for (int i = 0; i <= n; i++)
    {
        ans[i] = 0;
    }
 
    // Fill answer array by comparing
    // minimums of all lengths computed
    // using left[] and right[]
    for (int i = 0; i < n; i++)
    {
        // length of the interval
        int len = right[i] - left[i] - 1;
 
        // arr[i] is a possible answer for
        // this length 'len' interval, check x
        // if arr[i] is more than max for 'len'
        ans[len] = Math.Max(ans[len], arr[i]);
    }
 
    // Some entries in ans[] may not be
    // filled yet. Fill them by taking
    // values from right side of ans[]
    for (int i = n - 1; i >= 1; i--)
    {
        ans[i] = Math.Max(ans[i], ans[i + 1]);
    }
 
    // Print the result
    for (int i = 1; i <= n; i++)
    {
        Console.Write(ans[i] + " ");
    }
}
 
// Driver Code
public static void Main(string[] args)
{
    printMaxOfMin(arr.Length);
}
}
 
// This code is contributed by Shrikant13

Javascript

<script>
    // An efficient Javascript program to find maximum
    // of all minimums of windows of different size
    let arr = [10, 20, 30, 50, 10, 70, 30];
    function printMaxOfMin(n)
    {
     
        // Used to find previous and next smaller
        let s = [];
 
        // Arrays to store previous
        // and next smaller
        let left = new Array(n + 1);
        left.fill(0);
        let right = new Array(n + 1);
        right.fill(0);
 
        // Initialize elements of left[]
        // and right[]
        for (let i = 0; i < n; i++)
        {
            left[i] = -1;
            right[i] = n;
        }
 
        // Fill elements of left[] using logic discussed on
        // https://www.geeksforgeeks.org/next-greater-element/
        for (let i = 0; i < n; i++)
        {
            while (s.length > 0 && arr[s[s.length - 1]] >= arr[i])
            {
                s.pop();
            }
 
            if (s.length > 0)
            {
                left[i] = s[s.length - 1];
            }
 
            s.push(i);
        }
 
        // Empty the stack as stack is going
        // to be used for right[]
        while (s.length > 0)
        {
            s.pop();
        }
 
        // Fill elements of right[] using
        // same logic
        for (let i = n - 1 ; i >= 0 ; i--)
        {
            while (s.length > 0 && arr[s[s.length - 1]] >= arr[i])
            {
                s.pop();
            }
 
            if (s.length > 0)
            {
                right[i] = s[s.length - 1];
            }
 
            s.push(i);
        }
 
        // Create and initialize answer array
        let ans = new Array(n + 1);
        ans.fill(0);
        for (let i = 0; i <= n; i++)
        {
            ans[i] = 0;
        }
 
        // Fill answer array by comparing
        // minimums of all lengths computed
        // using left[] and right[]
        for (let i = 0; i < n; i++)
        {
         
            // length of the interval
            let len = right[i] - left[i] - 1;
 
            // arr[i] is a possible answer for
            // this length 'len' interval, check x
            // if arr[i] is more than max for 'len'
            ans[len] = Math.max(ans[len], arr[i]);
        }
 
        // Some entries in ans[] may not be
        // filled yet. Fill them by taking
        // values from right side of ans[]
        for (let i = n - 1; i >= 1; i--)
        {
            ans[i] = Math.max(ans[i], ans[i + 1]);
        }
 
        // Print the result
        for (let i = 1; i <= n; i++)
        {
            document.write(ans[i] + " ");
        }
    }
     
    printMaxOfMin(arr.length);
    
   // This code is contributed by decode2207.
</script>
Producción

70 30 20 10 10 10 10 

Análisis de Complejidad:  

  • Complejidad temporal: O(n). 
    Cada subtarea en este enfoque requiere tiempo lineal.
  • Espacio Auxiliar : O(n). 
    Uso de la pila para calcular el siguiente mínimo y arrays para almacenar los resultados intermedios.

Este artículo es una contribución de Ekta Goel y Ayush Govil . Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *