Rechteckige Region in einem Array

9

Wenn man eine N * N-Matrix mit 1en und einer Zahl von 0 gibt und eine ganze Zahl k gibt, was ist dann die beste Methode, um eine rechteckige Region zu finden, die k 1 enthält?

    
Flash 18.09.2010, 13:11
quelle

2 Antworten

2

Betrachten Sie dieses einfachere Problem:

  

Wenn Sie einen Vektor der Größe N angeben, der nur die Werte 1 und 0 enthält, suchen Sie eine Untersequenz, die genau k Werte von 1 enthält.

Sei A der gegebene Vektor und S[i] = A[1] + A[2] + A[3] + ... + A[i] , was bedeutet, wie viele 1s es in der Untersequenz A[1..i] gibt.

Für jedes i interessiert uns die Existenz von j <= i , also S[i] - S[j-1] == k .

Wir können dies in O(n) mit einer Hash-Tabelle finden, indem wir die folgende Beziehung verwenden:

S[i] - S[j-1] == k => S[j-1] = S[i] - k

%Vor%

Nun können wir dies verwenden, um Ihr gegebenes Problem in O(N^3) zu lösen: Für jede Sequenz von Zeilen in Ihrer gegebenen Matrix (es gibt O(N^2) Reihenfolgen), betrachten Sie diese Sequenz, um einen Vektor darzustellen und den vorherigen Algorithmus anzuwenden darauf. Die Berechnung von S ist im Matrixfall etwas schwieriger, aber es ist nicht so schwer herauszufinden. Lassen Sie mich wissen, wenn Sie weitere Informationen benötigen.

Aktualisierung: So funktioniert der Algorithmus in der folgenden Matrix: k = 12 :

%Vor%

Betrachten Sie die erste Zeile allein:

%Vor%

Betrachte es als Vektor 0 1 1 1 1 0 und wende den Algorithmus für das einfachere Problem an: wir finden, dass es keine Subsequenz gibt, die bis zu 12 addiert, also gehen wir weiter.

Betrachten Sie die ersten beiden Zeilen:

%Vor%

Betrachte sie als den Vektor 0+0 1+1 1+1 1+1 1+1 0+0 = 0 2 2 2 2 0 und wende den Algorithmus für das einfachere Problem an: wieder keine Untersequenz, die zu 12 addiert, also mach weiter.

Betrachten Sie die ersten drei Zeilen:

%Vor%

Betrachten Sie sie als Vektor 0 3 3 3 3 0 und wenden Sie den Algorithmus für das einfachere Problem an: Wir finden die Sequenz, die an Position 2 beginnt und an Position 5 endet, als Lösung. Von diesem können wir das gesamte Rechteck mit einfacher Buchhaltung erhalten.

    
IVlad 18.09.2010, 14:13
quelle
3

Ich kann es mit O machen (N ^ 3 * log (N)), aber sicher ist die beste Lösung schneller. Zuerst erstellen Sie eine weitere N * N-Matrix B (die Anfangsmatrix ist A). Die Logik von B ist die folgende:

%Vor%

Sie können B für O (N ^ 2) durch dynamische Programmierung auswerten: B [i] [j] = B [i-1] [j] + B [i] [j-1] - B [i- 1] [j-1] + A [i] [j].

Nun ist es sehr einfach, dieses Problem mit O (N ^ 4) zu lösen, indem man über den gesamten rechten unteren Teil (i = 1..N, j = 1..N, O (N ^ 2)) nach links iteriert -bottom (z = 1..j, O (N)), und rechts-oben (t = 1..i, O (N)) und Sie erhalten die Anzahl der Einsen in diesem Rechteck mit Hilfe von B:

%Vor%

Wenn du genau k: k == sum_of_ones hast, dann raus aus dem Ergebnis.

Um es N ^ 3 * log (N) zu machen, sollten Sie rechts-oben durch binäre Suche finden (also nicht nur alle möglichen Zellen iterieren).

    
Max 18.09.2010 14:12
quelle

Tags und Links