Yo te paso a través de algunas soluciones de dificultad creciente/decreciente complejidad en tiempo de ejecución.
En primer lugar, una solución de fuerza bruta. Genera todos los rectángulos posibles. Puede hacerlo iterando a través de cada par de puntos (r1, c1) (r2, c2) con r1 ≤ r2 y c1 ≤ c2 (se puede hacer con 4 bucles for). Si un rectángulo no contiene un 0, se compara el área con el área más grande encontrada hasta ahora. Esto es un O (R^3C^3).
Podemos acelerar el cheque rectángulo válida a O (1). Hacemos esto haciendo un DP donde dp (r, c) almacena el número de 0 en el rectángulo ((1, 1), (r, c)).
- dp (r, 0) = 0
- dp (0, c) = 0
- dp (r, c) = dp (r-1, c) + dp (r, c- 1) -dp (r1, c1) + (matriz [r] [c] 0:? 1)
Entonces el número de 0 de en ((r1, c1), (r2, c2)) es
- nzeroes (r1, c1, r2, c2) = dp [R2] [c2] -dp [r1 -1] [c2] -dp [R2] [c1 -1] + dp [ r1 -1] [c1 -1]
A continuación, puede comprobar si un rectángulo es válida por nzeroes (R1, C1, R2, C2) == 0.
Hay un O (R^2C) solución para esto el uso de un DP simple y una pila. El DP funciona por columna, al encontrar el número de 1 celda sobre una celda hasta el próximo 0. El dp es el siguiente:
dp (r, 0) = 0 dp (r, c) = 0 si matriz [r] [c] == 0 dp (r, c) = dp (r-1, c) + 1 en caso contrario
a continuación, hacer lo siguiente:
area = 0
for each row r:
stack = {}
stack.push((height=0, column=0))
for each column c:
height = dp(r, c)
c1 = c
while stack.top.height > height:
c1 = stack.top.column
stack.pop()
if stack.top.height != height:
stack.push((height=height, column=c1))
for item in stack:
a = (c - item.column + 1) * item.height
area = max(area, a)
también es posible resuelva el problema en O (RC) usando tres DP:
- h (r, c): si comenzamos en (r, c) y vamos hacia arriba, ¿cuántas células 1 encontramos antes del primer 0?
- l (r, c): ¿a qué distancia podemos extender un rectángulo con la esquina inferior derecha en (r, c) y la altura h (r, c)?
- r (r, c): ¿hasta qué punto podemos extender un rectángulo con la esquina inferior izquierda en (r, c) y la altura h (r, c)?
Los tres relaciones de recurrencia son:
- h (0, c) = 0
- h (r, c) = 0 si la matriz [r] [c] == 0
h (r, c) = h (r-1, c) 1 de otro modo
l (r, 0) = 0
- l (r, c) = cp si matriz [r- 1] [c] == 0
l (r, c) = min (l (r - 1, c), c - p) de lo contrario
r (r, C + 1) = 0
- r (r, c) = pc si matriz [r-1] [c] == 0
- r (r, c) = min (r (r - 1, c), PC) de lo contrario
donde p es la columna del 0 anterior a medida que llenamos l de izquierda a derecha yr de derecha a izquierda.
La respuesta es entonces:
- Max_r, c (h (r, c) * (l (r, c) + r (r, c) - 1))
Esto funciona debido a la observación de que el rectángulo más grande siempre tocará un 0 (considerando que el borde está cubierto por 0) en los cuatro lados. Al considerar todos los rectángulos con al menos la parte superior, la izquierda y la derecha tocando un 0, cubrimos todos los rectángulos candidatos. Genera todos los rectángulos posibles. Puede hacerlo iterando a través de cada par de puntos (r1, c1) (r2, c2) con r1 ≤ r2 y c1 ≤ c2 (se puede hacer con 4 bucles for). Si un rectángulo no contiene un 0, se compara el área con el área más grande encontrada hasta ahora.
Nota: Adapté lo anterior de una respuesta que escribí here - consulte la sección "mamá de Ben". En ese escrito, los 0 son árboles. Ese informe también tiene un mejor formato.
gracias por una buena solución. – RATHI
Muchas gracias. Grandes soluciones. –