Oto algorytm O(numCols*numLines^2)
. Niech S[i][j] = sum of the first i elements of column j.
będę pracować algorytmu na przykładzie:
M
1 1 0 0 1 0
0 1 1 1 0 1
1 1 1 1 0 0
0 0 1 1 0 0
Mamy:
S
1 1 0 0 1 0
1 2 1 1 1 1
2 3 2 2 1 1
2 3 3 3 1 1
Rozważmy teraz problem znalezienia maksymalnej subarray wszystkich tych, w jednowymiarowej tablicy . Problem ten można rozwiązać za pomocą tego prostego algorytmu:
append 0 to the end of your array
max = 0, temp = 0
for i = 1 to array.size do
if array[i] = 1 then
++temp
else
if temp > max then
max = temp
temp = 0
Na przykład, jeśli masz ten 1d tablicy:
1 2 3 4 5 6
1 1 0 1 1 1
ty chcesz to zrobić:
Najpierw dołączyć 0
:
1 2 3 4 5 6 7
1 1 0 1 1 1 0
Zauważ, że za każdym razem, gdy trafisz na 0
, wiesz, gdzie ciąg przylegających końców. Dlatego jeśli utrzymujesz sumę bieżącą (zmienną temp
) dla bieżącej liczby, możesz porównać tę wartość z maksymalną wartością (max
) po zejściu do zera, a następnie zresetować sumę bieżącą. Daje to maksymalną długość ciągłej sekwencji zmiennych w zmiennej max
.
Teraz możesz użyć tego podalgorytu, aby znaleźć rozwiązanie swojego problemu. Najpierw dołącz kolumnę 0
do macierzy. Następnie obliczyć S
.
Następnie:
max = 0
for i = 1 to M.numLines do
for j = i to M.numLines do
temp = 0
for k = 1 to M.numCols do
if S[j][k] - S[i-1][k] = j - i + 1 then
temp += j - i + 1
else
if temp > max then
max = temp
temp = 0
Zasadniczo, dla każdej możliwej wysokości w subarray (istnieją O(numLines^2)
możliwych wysokościach), można znaleźć jeden z maksymalnej powierzchni mającej tę wysokość przy zastosowaniu algorytmu do jednowymiarowej tablicy (w O(numCols)
).
Rozważmy następujący "obraz":
M
1 1 0 0 1 0 0
i 0 1 1 1 0 1 0
j 1 1 1 1 0 0 0
0 0 1 1 0 0 0
Oznacza to, że mamy wysokość j - i + 1
stałe. Teraz weź wszystkie elementy macierzy, które są między i
i j
włącznie:
0 1 1 1 0 1 0
1 1 1 1 0 0 0
Zauważ, że podobny problem jednowymiarowy.Podsumujmy kolumny i zobaczyć, co mamy:
1 2 2 2 0 1 0
Teraz problem sprowadza się do jednowymiarowego przypadku, z tą różnicą, że musimy wybrać podciąg ciągłych j - i + 1
(co jest 2
w tym przypadku) wartości. Oznacza to, że każda kolumna w naszym "oknie" musi być pełna. Możemy to sprawdzić skutecznie, korzystając z matrycy S
.
Aby zrozumieć, jak działa S
, należy ponownie rozważyć sprawę jednowymiarową: niech s[i] = sum of the first i elements of the vector a
. Więc jaka jest suma podciągu a[i..j]
? Jest to suma wszystkich elementów do wartości a[j]
włącznie, łącznie z sumą wszystkich wartości do włącznie z a[i-1]
, co oznacza s[j] - s[i-1]
. Sprawa 2d działa tak samo, z tym że mamy dla każdej kolumny s
.
Mam nadzieję, że jest to jasne, jeśli masz więcej pytań, zapytaj.
Nie wiem, czy to pasuje do twoich potrzeb, ale myślę, że istnieje również algorytm O(numLines*numCols)
oparty na dynamicznym programowaniu. Nie mogę tego jeszcze rozgryźć, z wyjątkiem przypadku, w którym podobieństwo, na które masz ochotę, jest kwadratowe. Ktoś może mieć lepszy wgląd, więc poczekaj trochę więcej.
Jak dokładnie udało Ci się stworzyć algorytm O (n^n)? Nawet proste rozwiązanie (sprawdź wszystkie n^4 prostokąty i sprawdź je) uruchomi się w O (n^6). –