O (n^2) es posible. Supongo que es óptimo, ya que tienes n^2 células.
Observe que la esquina superior izquierda y la esquina inferior derecha de cualquier cuadrado se encuentran en la misma diagonal.
Ahora si pudiéramos procesar cada diagonal en O (n) tiempo, tendríamos un algoritmo de tiempo O (n^2).
Supongamos que tenemos un candidato para la esquina superior izquierda. Podemos calcular el número de celdas negras continuas debajo de él, y a la derecha del mismo, tomar el mínimo de los dos y llamarlo T.
Para un candidato de la esquina inferior derecha, podemos calcular el número de celdas negras continuas a la izquierda, y arriba y tome el mínimo de los dos, llámelo B.
Una vez que tenemos los dos números T y B, podemos decir si el candidato arriba a la izquierda, abajo a la derecha de hecho, danos un cuadrado con todos los bordes negros.
Ahora esos dos números se pueden calcular para cada celda, en O (n^2) tiempo haciendo cuatro pasadas a través de la matriz completa (¿Cómo?).
Así que supongamos que ya está hecho.
Considere ahora una diagonal. Nuestro objetivo es encontrar un par superior izquierdo, inferior derecho a lo largo de esta diagonal en el tiempo O (n).
Supongamos que tenemos las T calculadas en una matriz T [1 ... m] donde m es la longitud de la diagonal. Del mismo modo, tenemos una matriz B [1 ... m]. T [1] corresponde al extremo superior izquierdo de la diagonal y T [m] a la inferior derecha. De manera similar con B.
Ahora procesamos la diagonal de la siguiente manera, para cada candidato de la parte superior izquierda i, tratamos de encontrar un candidato de abajo a la derecha j que dará el cuadrado más grande. Observe que j> = i. También note que si (i, j) es un candidato, entonces (i ', j) no es, donde i'> i.
Tenga en cuenta que i y j forman un cuadrado si T[i] >= j-i+1
y B[j] >= j-i+1
.
es decir, T[i] +i - 1 >= j
y B[j] -j - 1 >= -i
.
Así que formamos nuevas matrices tales como TL[k] = T[k] + k -1
y BR[k] = B[k] -k - 1
.
Por lo tanto, dada la TL dos nuevas matrices y BR, y un i, tenemos que responder a las siguientes preguntas:
¿Cuál es el j grande tal que TL [i]> = j y BR [j ]> = -i?
Supongamos ahora que pudimos procesar BR para consultas de rango máximo (se puede hacer en O (m) tiempo).
Ahora dado TL [i], en el rango [i, TL [i]] encontramos el valor máximo de BR, digamos BR [j1].
Ahora, si BR [j1]> = -i, encontramos el máximo de BR en el rango [j1, TL [i]] y continuamos de esta manera.
Una vez que encontramos el candidato (TL [i], BR [j]), podemos ignorar la matriz BR [1 ... j] para el futuro i.
Esto nos permite procesar cada diagonal en O (n) tiempo, dando un algoritmo total O (n^2).
He omitido muchos detalles y he dado un boceto, ya que ya era demasiado largo. Siéntase libre de editar esto con aclaraciones.
Phew.
idea loca: si su matriz es enorme, quizás una transformada discreta de Fourier con una base de espacio mome bien elegida puede dar una buena estimación al * tamaño * de la matriz cuadrada resultante. Sin embargo, ni idea de si eso es práctico. –
Para cada celda, la cantidad lineal de trabajo me suena a O (n^3). – simonpie
¿Podemos ver su algoritmo 0 (n^2)? :) Vi una discusión http://discuss.techinterview.org/default.asp?interview.11.445656.19 donde todos estaban estancados en 0 (n^3). –