[Serie Leetcode] [algoritmo] [difícil] de agua de lluvia

tema:

enlaces a los temas:  https://leetcode-cn.com/problems/trapping-rain-water/

 

Ideas de resolución de problemas:

Método A: Programación Dinámica

Cada ubicación puede ahorrar agua, se trata de la posición actual de la máxima altura en ambos lados de la altura más pequeña, menos corriente

En tanto que sabemos de la altura máxima de cada posición, se puede calcular la posición actual del almacenamiento de agua

Pero si la violencia siempre travesía alrededor de la posición actual de la altura máxima, la eficiencia es muy baja

Es posible atravesar antes de la primera pre-procesamiento de la vuelta de la altura máxima de cada lugar, y luego atravesar el tiempo, no termina siempre que atraviesa todos los datos a la izquierda

En pretratamiento sobre la altura máxima para cada posición, utilizando la idea de DP:

  1. index = 0, la altura máxima de la izquierda de su propio
  2. índice> 0, la altura máxima de la max izquierda (índice - 1, index)
  3. Del mismo modo la altura máxima de la derecha, pero modificado para atravesar de atrás hacia adelante

Específicamente se ilustra como sigue:

La altura máxima de cada posición en la derecha como se muestra a continuación (la parte amarilla de la altura de cada columna de cuadrícula, la parte azul de la columna a la derecha de los valores más altos):

Cada posición de altura máxima desde la izquierda como se muestra a continuación:

región figura superposición de dos:

Esta sección es el área

 

Segundo método: Pila

Mantenimiento cuando se atraviesa una posición de pila si la altura de la columna actual es menor que la altura de la cabeza de la columna de la pila, la altura de la columna actual de la pila; si la pila es mayor que la altura de la columna, a continuación, la pila de elementos en la pila se calculan secuencialmente capacidad de almacenamiento, como se muestra :

Traversal comienza, el primer elemento directamente a la pila (la pila se almacena en el índice de matriz para el cálculo de la longitud)

Apilar antes del segundo elemento, encontrar una altura de columna más alta que la anterior, esta vez la primera pila en una columna, una altura de columna de cerca de dos columnas en la determinación

En este caso no se encontraron pilares de la izquierda, por lo que no calcular el área, directamente a la pila 1, continúe con el próximo ciclo

Para continuar para atravesar la posición subíndice 3, columna 3 se encontró mayor que la altura 2

En este momento, la pila 3 antes de que el área efectiva 3 antes del cálculo, la lógica de cálculo es: altura mínima alrededor de cada columna, la altura de la columna menos el actual, multiplicado por la longitud

Para la posición de la etiqueta 2, una fórmula de cálculo específico es el siguiente:

  1. La altura mínima de aproximadamente MIN_HEIGHT = min (altura [3], la altura [1]) = min (2, 1) = 1
  2. La corriente current_height height = altura [2] = 0
  3. Longitud = 3 - 1 - 1 = 1
  4. El área efectiva área = (MIN_HEIGHT - current_height) * Longitud = (1 - 0) * 1 = 1

Para proceder a un juicio, no se encontró la pila deja la columna 1, el área efectiva se calcula detuvo en este punto, la pila 3, el recorrido sigue:

Atravesando el índice es 6, una altura de la columna más alta que la parte superior de la pila 5, para continuar según el anterior área de cálculo lógico, un aumento de área, donde después de la pila como sigue:

En este momento, la parte superior de la pila está etiquetada 4, 6 pero la altura a la altura 4 de la misma, atraviesan la pila se detiene, después de la pila 6, traversal sigue:

7 atravesados, altitudes superiores a 6 comienza de nuevo el recorrido de la pila, la altura de la columna 6 en el primero a la izquierda y la posición actual de la alineación de las pilas 7, la lógica es la siguiente:

  1. La altura mínima de aproximadamente MIN_HEIGHT = min (altura [4], la altura [7]) = min (1, 3) = 1
  2. La altura current_height actual = altura (6) = 1
  3. Longitud = 7 - 4 - 1 = 2
  4. El área efectiva área = (MIN_HEIGHT - current_height) * Longitud = (1 - 1) * 0 = 0

Después de este tiempo la pila 6, el elemento superior se determina para continuar, encontramos altitudes más alta que la altura de 4, continuar para atravesar la pila, donde la pila en este momento es el siguiente:

4 posición lógica de cálculo en este momento es el siguiente:

  1. La altura mínima de aproximadamente MIN_HEIGHT = min (altura [3], la altura [7]) = min (2, 3) = 2
  2. La altura current_height actual = altura (4) = 1
  3. Longitud = 7 - 3 - 1 = 3
  4. El área efectiva área = (MIN_HEIGHT - current_height) * Longitud = (2 - 1) * 3 = 3

En este momento, la pila es el siguiente:

De acuerdo con esta lógica continúa a través, hasta que todos los pilares atravesados

 

Método tres: el doble puntero

puntero de cabeza a la izquierda, a la derecha del puntero de la cola atraviesa el puntero doble, zona de ubicación actual, existen los siguientes casos:

  1. Si la altura [dejó] Area> Altura [derecha], la posición actual de la [derecha] determinada por la altura
  2. Otros casos, [izquierda] se determina por la altura

Tip Organigrama específicamente como sigue:

Variable como sigue:

  1. left_max: altura máxima de la iteración actual de la izquierda, se inicializa a 0
  2. right_max: corriente que atraviesa la derecha de la altura máxima, se inicializa a 0
  3. la izquierda: izquierda-puntero, inicializado a 0
  4. derecha: el puntero derecho, se inicializa a len (altura) - 1, es decir, el último índice elemento
  5. área: el área acumulada, se inicializa a cero

La posición inicial es la siguiente:

La altura Descubrimiento [derecha]> Altura [izquierda], calcular el área de la izquierda, la siguiente lógica:

  1. Que la altura [izquierda] y tamaño left_max, encontrar altura de la caja [izquierda] = 0, left_max = 0, sin calcular el área
  2. Hacia la derecha a la izquierda = izquierda + 1

Después del procesamiento puntero como sigue:

Igualdad de izquierda y derecha, la lógica de procesamiento en este momento es la siguiente:

  1. Que la altura [izquierda] y tamaño left_max, encontrar la altura [izquierda]> left_max, actualizar left_max = altura [izquierda], sin contar la zona
  2. Mover a la derecha a la izquierda (o de izquierda a mover hacia la derecha, la misma razón)

El caso se ha tratado de la siguiente manera:

En este momento, la lógica de procesamiento es el siguiente:

  1. Altura [izquierdo] <left_max, calculado en el área izquierda = left_max - Altura [dejó] = 1 - 0 = 1
  2. Continuar hacia la derecha para mover hacia la izquierda

Resultados y posterior procesamiento se completa ilustran como sigue:

 

la implementación del código:

Método uno:

class Solution:
    def trap(self, height: List[int]) -> int:
        if 0 == len(height):
            return 0
        
        left_max, right_max = [0] * len(height), [0] * len(height)
        left_max[0] = height[0]
        right_max[-1] = height[-1]
        
        for index in range(1, len(height)):
            left_max[index] = max(height[index], left_max[index - 1])
            
        for index in range(len(height) - 2, -1, -1):
            right_max[index] = max(height[index], right_max[index + 1])
            
        area = 0
        for index in range(len(height)):
            area += min(left_max[index], right_max[index]) - height[index]
            
        return area

 

Segundo método:

class Solution:
    def trap(self, height: List[int]) -> int:
        area = 0
        rec = []
        for index in range(len(height)):
            while 0 < len(rec) and height[index] > height[rec[-1]]:
                last_idx = rec[-1]
                rec.pop()
                if 0 == len(rec):
                    break
                    
                distance = index - rec[-1] - 1
                tmp_height = min(height[index], height[rec[-1]]) - height[last_idx]
                area += distance * tmp_height
                
            rec.append(index)
            
        return area
            

 

Método tres:

class Solution:
    def trap(self, height: List[int]) -> int:
        left_max, right_max = 0, 0
        left, right = 0, len(height) - 1
        area = 0
        while left < right:
            if height[left] > height[right]:
                if height[right] >= right_max:
                    right_max = height[right]
                else:
                    area += right_max - height[right]
                    
                right -= 1
            else:
                if height[left] >= left_max:
                    left_max = height[left]
                else:
                    area += left_max - height[left]
                    
                left += 1
        
        return area

 

Publicados 100 artículos originales · ganado elogios 4 · Vistas 1470

Supongo que te gusta

Origin blog.csdn.net/songyuwen0808/article/details/105312639
Recomendado
Clasificación