Nehmen wir zunächst an, wir verwenden ein Quadrat.
1 2 3
2 3 4
3 4 5
1. Ein Quadrat suchen
Ich würde eine binäre Suche auf der Diagonale verwenden. Das Ziel ist es, die kleinere Zahl zu lokalisieren, die nicht streng niedriger als die Zielzahl ist.
Angenommen, ich suche zum 4Beispiel, dann würde ich am Ende 5bei suchen (2,2).
Dann bin ich mir sicher, dass wenn 4es in der Tabelle ist, es an einer Position entweder (x,2)oder (2,x)mit xin ist [0,2]. Nun, das sind nur 2 binäre Suchen.
Die Komplexität ist nicht entmutigend: O(log(N))(3 binäre Suchen nach Längenbereichen N)
2. Suche nach einem rechteckigen, naiven Ansatz
Natürlich wird es etwas komplizierter, wenn Nund Munterscheiden Sie sich (mit einem Rechteck), betrachten Sie diesen entarteten Fall:
1 2 3 4 5 6 7 8
2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17
Nehmen wir an, ich suche 9... Der diagonale Ansatz ist immer noch gut, aber die Definition von diagonalen Änderungen. Hier ist meine Diagonale [1, (5 or 6), 17]. Nehmen wir an, ich habe abgeholt [1,5,17], dann weiß ich, dass wenn 9es in der Tabelle ist, es entweder im Unterabschnitt ist:
5 6 7 8
6 7 8 9
10 11 12 13 14 15 16
Dies gibt uns 2 Rechtecke:
5 6 7 8 10 11 12 13 14 15 16
6 7 8 9
So können wir zurückgreifen! wahrscheinlich beginnend mit dem mit weniger Elementen (obwohl es uns in diesem Fall umbringt).
Ich sollte darauf hinweisen, dass 3wir , wenn eine der Dimensionen kleiner als ist , die diagonalen Methoden nicht anwenden können und eine binäre Suche verwenden müssen. Hier würde es bedeuten:
- Wenden Sie die binäre Suche auf an
10 11 12 13 14 15 16, nicht gefunden
- Wenden Sie die binäre Suche auf an
5 6 7 8, nicht gefunden
- Wenden Sie die binäre Suche auf an
6 7 8 9, nicht gefunden
Es ist schwierig, denn um eine gute Leistung zu erzielen, sollten Sie je nach allgemeiner Form zwischen mehreren Fällen unterscheiden.
3. Suche nach einem rechteckigen, brutalen Ansatz
Es wäre viel einfacher, wenn wir uns mit einem Quadrat befassen würden ... also lasst uns einfach die Dinge zusammenfassen.
1 2 3 4 5 6 7 8
2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17
17 . . . . . . 17
. .
. .
. .
17 . . . . . . 17
Wir haben jetzt ein Quadrat.
Natürlich werden wir diese Zeilen wahrscheinlich NICHT erstellen, wir könnten sie einfach emulieren.
def get(x,y):
if x < N and y < M: return table[x][y]
else: return table[N-1][M-1] # the max
es verhält sich also wie ein Quadrat, ohne mehr Speicher zu belegen (auf Kosten der Geschwindigkeit, wahrscheinlich abhängig vom Cache ... na ja: p)
[[1 1][1 1]]?