[Algoritmo de combate] Genera una matriz de valores máximos de ventana

[Algoritmo de combate] Genera una matriz de valores máximos de ventana

Hemos realizado preguntas algorítmicas, la dificultad de las preguntas se divide en cuatro niveles: "Senior, Wei, School y General". El módulo de este problema de algoritmo es el que tiene una longitud relativamente pequeña. El primero es dar una descripción de un problema, y ​​luego usaré mis ideas para hacer este problema, hoy se considera como el primer problema del algoritmo, probemos primero con el agua.

Descripción del problema (nivel: Wei)

有一个整型数组arr和一个大小为w的窗口从数组的最左边滑到最右边,窗口每次向右边滑一个位置。
例如,数组为[4,3,1,5,4,3,7,5],窗口大小为5时:
[4 3 1 5 4] 3 7 5  max = 5
4 [3 1 5 4 3] 7 5  max = 5
4 3 [1 5 4 3 7] 5  max = 7
4 3 1 [5 4 3 7 5]   max = 7
即窗口最大值数组为 result = {5, 5,7,7}

responder:

Para un problema, generalmente pienso en usar un método violento para hacerlo la primera vez y luego optimizarlo lentamente más tarde.

Obviamente, es bastante simple usar el método de fuerza bruta para este problema. Cada vez que la ventana se mueve un lugar a la derecha, recorremos los elementos w en la ventana cada vez y luego encontramos el valor máximo de la ventana en este momento. La complejidad temporal de este método es O (wn). el código se muestra a continuación:

//暴力法求解
   public static int[] getMaxWindow(int[] arr, int w) {
       if (w < 1 || arr == null || arr.length < w) {
           return null;
       }
       int[] result = new int[arr.length - w + 1];
       int index = 0;
       //暴力求解直接从第 w-1个元素开始遍历
       for (int i = w - 1; i < arr.length; i++) {
           int max = arr[i];
           //找出最大值
           for (int k = i; k > i - w; k--) {
               if (max < arr[k]) {
                   max = arr[k];
               }
           }
           result[index++] = max;
       }
       return result;
   }

Nota: puede tirar hacia la izquierda y hacia la derecha

Todos piensan en una pregunta, por ejemplo, para la matriz en el ejemplo de este momento:

En el primer recorrido, max = 5

[Algoritmo de combate] Genera una matriz de valores máximos de ventana

En el segundo recorrido, max = 5

[Algoritmo de combate] Genera una matriz de valores máximos de ventana

Cuando usamos el método de fuerza bruta, ya sea por primera vez o por segunda vez, recorrimos todos los elementos de la ventana una vez para encontrar el valor máximo, pero ¿es realmente necesario?

Durante el primer recorrido, encontramos max = 5, por lo que en el segundo recorrido, dentro del rango de la ventana, ¿los dos números 1, 3 a la izquierda de max = 5 siguen siendo el máximo? En otras palabras, ¿es necesario atravesar los elementos de la ventana en el lado izquierdo de max = 5?

Obviamente, la ventana a la izquierda de max = 5 ya no necesita ser recorrida, es decir, no puede ser el valor máximo de la ventana.

Y max = 5, ¿es el 4 del lado derecho el valor máximo de la ventana? Dado que la ventana continuará moviéndose hacia la derecha, el elemento de la ventana a la derecha de max = 5 aún puede ser el valor máximo de una determinada ventana.

Por lo tanto, podemos usar una cola de dos vías para registrar el subíndice que puede convertirse en el valor máximo de la ventana, tenga en cuenta que aquí es posible.

Como solo max = 5, el 1,3 frente a él no puede ser el valor máximo de la ventana, y el 4 a la derecha aún puede ser el valor máximo de la ventana. Y esta cola está ordenada, el encabezado de la cola es siempre el valor máximo en la cola,

Permítanme demostrar con esta pregunta. Usamos la matriz result [] para almacenar el valor máximo de la ventana.

1 、 resultado [0] = 5

[Algoritmo de combate] Genera una matriz de valores máximos de ventana

2 、 resultado [1] = 5;

[Algoritmo de combate] Genera una matriz de valores máximos de ventana

3 、 resultado [2] = 7

[Algoritmo de combate] Genera una matriz de valores máximos de ventana

Todos los demás deben quitarse de la cola, porque el 5, 4 y 3 antes del 7 no pueden ser el valor máximo de la ventana.

4 、 resultado [3] = 7

[Algoritmo de combate] Genera una matriz de valores máximos de ventana

El recorrido está completo. La complejidad temporal de este método es O (n).

Aquí solo proporciono ideas y prácticas generales, y todavía hay muchos detalles que necesitan atención en la implementación del código específico. El código de implementación se proporciona a continuación y el código se explicará en detalle.

//优化
   public static int[] getMaxWindow2(int[] arr, int w) {
       if (w < 1 || arr == null || arr.length < w) {
           return null;
       }
       //用来保存成为最大窗口的元素
       int[] result = new int[arr.length - w + 1];
       int index = 0;
       //用链表从当双向队列。
       LinkedList<Integer> temp = new LinkedList<>();
       //刚才演示的时候,我i直接从i = w-1那里开始演示了。
       for (int i = 0; i < arr.length; i++) {
           //如果队列不为空,并且存放在队尾的元素小于等于当前元素,那么
           //队列的这个元素就可以弹出了,因为他不可能会是窗口最大值。
           //【当前元素】指的是窗口向右移动的时候新加入的元素。
           while (!temp.isEmpty() && arr[temp.peekLast()] <= arr[i]) {
               temp.pollLast();//把队尾元素弹出
           }
           //把【当前元素】的下边加入到队尾
           temp.addLast(i);
           //如果队首的元素不在窗口范围内,则弹出
           if (temp.peekFirst() == i - w) {
               temp.pollFirst();//
           }
           if (i >= w - 1) {
               //由于队首存放的是最大值,所以队首总是对应窗口的最大值元素
               result[index++] = arr[temp.peekFirst()];
           }
       }
       return result;
   }

Para ser honesto, es un poco incómodo leer el código en WeChat. Es mejor si estás navegando en una computadora. Estoy considerando si usar capturas de pantalla, pero si es una captura de pantalla, algunas personas no podrán copiar el código si quieren copiar el código. Considere empaquetar el código y responderá para obtenerlo en segundo plano.

  • Fin-
    Lectura recomendada:
    lo guiará paso a paso para aprender la complejidad del tiempo y la complejidad del espacio.
    Hablar de NAT: ¿Qué? ¿Qué diablos son la IP global y la IP privada?

[Algoritmo de combate] Genera una matriz de valores máximos de ventana

Supongo que te gusta

Origin blog.51cto.com/15015171/2555353
Recomendado
Clasificación