Máximo de ventana deslizante (Máximo de todos los subarreglos de tamaño k) utilizando la pila en tiempo O(n)

Dé una array arr[] de N enteros y otro entero k ≤ N . La tarea es encontrar el elemento máximo de cada subarreglo de tamaño k .

Ejemplos: 

Input: arr[] = {9, 7, 2, 4, 6, 8, 2, 1, 5}
 k = 3
Output: 9 7 6 8 8 8 5
Explanation:
Window 1: {9, 7, 2}, max = 9
Window 2: {7, 2, 4}, max = 7
Window 3: {2, 4, 6}, max = 6
Window 4: {4, 6, 8}, max = 8
Window 5: {6, 8, 2}, max = 8
Window 6: {8, 2, 1}, max = 8
Window 7: {2, 1, 5}, max = 5

Input: arr[] = {6, 7, 5, 2, 1, 7, 2, 1, 10}
 k = 2
Output: 7 7 5 2 7 7 2 10
Explanation:
Window 1: {6, 7}, max = 7
Window 2: {7, 5}, max = 7
Window 3: {5, 2}, max = 5
Window 4: {2, 1}, max = 2
Window 5: {1, 7}, max = 7
Window 6: {7, 2}, max = 7
Window 7: {2, 1}, max = 2
Window 8: {1, 10}, max = 10

Prerrequisito: Siguiente elemento mayor

Método: 
para cada índice, calcule el índice hasta el cual el elemento actual es máximo cuando el subarreglo comienza desde este índice, es decir, para cada índice i , un índice j ≥ i tal que max(a[i], a[i + 1], … a[j]) = a[i] . Llamémoslo max_upto[i]
Luego, el elemento máximo en la sub-array de longitud k a partir del i -ésimo índice se puede encontrar comprobando cada índice a partir de i hasta i + k – 1 para el cual max_upto[i] ≥ i + k – 1 (último índice de esa ventana). 

La estructura de datos de pila se puede utilizar para almacenar los valores en una ventana, es decir, el último elemento visitado o el elemento insertado anteriormente estará en la parte superior (elemento con el índice más cercano al elemento actual). 

Algoritmo:  

  1. Cree una array max_upto y una pila para almacenar índices. Empuje 0 en la pila.
  2. Ejecute un bucle desde el índice 1 hasta el índice n-1.
  3. Extraiga todos los índices de la pila, cuyos elementos (array[s.top()]) son menores que el elemento actual y actualice max_upto[s.top()] = i – 1 y luego inserte i en la pila.
  4. Extrae todos los índices de la pila y asigna max_upto[s.top()] = n – 1 .
  5. Crea una variable j = 0
  6. Ejecutar un ciclo de 0 a n – k, el contador de ciclo es i
  7. Ejecute un bucle anidado hasta que j < i o max_upto[j] < i + k – 1, incremente j en cada iteración.
  8. Imprime el j-ésimo elemento de la array.

Implementación:  

C++

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to print the maximum for
// every k size sub-array
void print_max(int a[], int n, int k)
{
    // max_upto array stores the index
    // upto which the maximum element is a[i]
    // i.e. max(a[i], a[i + 1], ... a[max_upto[i]]) = a[i]
 
    int max_upto[n];
 
    // Update max_upto array similar to
    // finding next greater element
    stack<int> s;
    s.push(0);
    for (int i = 1; i < n; i++) {
        while (!s.empty() && a[s.top()] < a[i]) {
            max_upto[s.top()] = i - 1;
            s.pop();
        }
        s.push(i);
    }
    while (!s.empty()) {
        max_upto[s.top()] = n - 1;
        s.pop();
    }
    int j = 0;
    for (int i = 0; i <= n - k; i++) {
 
        // j < i is to check whether the
        // jth element is outside the window
        while (j < i || max_upto[j] < i + k - 1)
            j++;
        cout << a[j] << " ";
    }
    cout << endl;
}
 
// Driver code
int main()
{
    int a[] = { 9, 7, 2, 4, 6, 8, 2, 1, 5 };
    int n = sizeof(a) / sizeof(int);
    int k = 3;
    print_max(a, n, k);
 
    return 0;
}

Java

// Java implementation of the approach
import java.util.*;
 
class GFG
{
 
    // Function to print the maximum for
    // every k size sub-array
    static void print_max(int a[], int n, int k)
    {
        // max_upto array stores the index
        // upto which the maximum element is a[i]
        // i.e. max(a[i], a[i + 1], ... a[max_upto[i]]) = a[i]
 
        int[] max_upto = new int[n];
 
        // Update max_upto array similar to
        // finding next greater element
        Stack<Integer> s = new Stack<>();
        s.push(0);
        for (int i = 1; i < n; i++)
        {
            while (!s.empty() && a[s.peek()] < a[i])
            {
                max_upto[s.peek()] = i - 1;
                s.pop();
            }
            s.push(i);
        }
        while (!s.empty())
        {
            max_upto[s.peek()] = n - 1;
            s.pop();
        }
        int j = 0;
        for (int i = 0; i <= n - k; i++)
        {
 
            // j < i is to check whether the
            // jth element is outside the window
            while (j < i || max_upto[j] < i + k - 1)
            {
                j++;
            }
            System.out.print(a[j] + " ");
        }
        System.out.println();
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int a[] = {9, 7, 2, 4, 6, 8, 2, 1, 5};
        int n = a.length;
        int k = 3;
        print_max(a, n, k);
 
    }
}
 
// This code has been contributed by 29AjayKumar

Python3

# Python3 implementation of the approach
 
# Function to print the maximum for
# every k size sub-array
def print_max(a, n, k):
     
    # max_upto array stores the index
    # upto which the maximum element is a[i]
    # i.e. max(a[i], a[i + 1], ... a[max_upto[i]]) = a[i]
 
    max_upto=[0 for i in range(n)]
 
    # Update max_upto array similar to
    # finding next greater element
    s=[]
    s.append(0)
 
    for i in range(1,n):
        while (len(s) > 0 and a[s[-1]] < a[i]):
            max_upto[s[-1]] = i - 1
            del s[-1]
         
        s.append(i)
 
    while (len(s) > 0):
        max_upto[s[-1]] = n - 1
        del s[-1]
 
    j = 0
    for i in range(n - k + 1):
 
        # j < i is to check whether the
        # jth element is outside the window
        while (j < i or max_upto[j] < i + k - 1):
            j += 1
        print(a[j], end=" ")
    print()
 
# Driver code
 
a = [9, 7, 2, 4, 6, 8, 2, 1, 5]
n = len(a)
k = 3
print_max(a, n, k)
 
# This code is contributed by mohit kumar

C#

// C# implementation of the approach
using System;
using System.Collections.Generic;
 
class GFG
{
 
    // Function to print the maximum for
    // every k size sub-array
    static void print_max(int []a, int n, int k)
    {
        // max_upto array stores the index
        // upto which the maximum element is a[i]
        // i.e. max(a[i], a[i + 1], ... a[max_upto[i]]) = a[i]
 
        int[] max_upto = new int[n];
 
        // Update max_upto array similar to
        // finding next greater element
        Stack<int> s = new Stack<int>();
        s.Push(0);
        for (int i = 1; i < n; i++)
        {
            while (s.Count!=0 && a[s.Peek()] < a[i])
            {
                max_upto[s.Peek()] = i - 1;
                s.Pop();
            }
            s.Push(i);
        }
        while (s.Count!=0)
        {
            max_upto[s.Peek()] = n - 1;
            s.Pop();
        }
        int j = 0;
        for (int i = 0; i <= n - k; i++)
        {
 
            // j < i is to check whether the
            // jth element is outside the window
            while (j < i || max_upto[j] < i + k - 1)
            {
                j++;
            }
            Console.Write(a[j] + " ");
        }
        Console.WriteLine();
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        int []a = {9, 7, 2, 4, 6, 8, 2, 1, 5};
        int n = a.Length;
        int k = 3;
        print_max(a, n, k);
 
    }
}
 
// This code has been contributed by 29AjayKumar

Javascript

<script>
 
// Javascript implementation of the approach
 
// Function to print the maximum for
// every k size sub-array
function print_max(a, n, k)
{
     
    // max_upto array stores the index
    // upto which the maximum element is a[i]
    // i.e. max(a[i], a[i + 1], ... a[max_upto[i]]) = a[i]
    let max_upto = new Array(n);
 
    // Update max_upto array similar to
    // finding next greater element
    let s = [];
    s.push(0);
     
    for(let i = 1; i < n; i++)
    {
        while (s.length != 0 &&
           a[s[s.length - 1]] < a[i])
        {
            max_upto[s[s.length - 1]] = i - 1;
            s.pop();
        }
        s.push(i);
    }
     
    while (s.length != 0)
    {
        max_upto[s[s.length - 1]] = n - 1;
        s.pop();
    }
    let j = 0;
    for(let i = 0; i <= n - k; i++)
    {
         
        // j < i is to check whether the
        // jth element is outside the window
        while (j < i || max_upto[j] < i + k - 1)
        {
            j++;
        }
        document.write(a[j] + " ");
    }
    document.write("<br>");
}
 
// Driver code
let a = [ 9, 7, 2, 4, 6, 8, 2, 1, 5 ];
let n = a.length;
let k = 3;
 
print_max(a, n, k);
 
// This code is contributed by patel2127
 
</script>
Producción: 

9 7 6 8 8 8 5

 

Análisis de Complejidad: 

  • Complejidad temporal: O(n). 
    Solo se necesitan dos recorridos de la array. Entonces la Complejidad del Tiempo es O(n).
  • Complejidad espacial: O(n). 
    Se requieren dos espacios adicionales de tamaño n.
     

https://youtu.be/m

-Dqu7csdJk?list=PLqM7alHXFySEQDk2MDfbwEdjd2svVJH9p
 

Publicación traducida automáticamente

Artículo escrito por monk789456123 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 *