Cóż, na początek załóżmy, że używamy kwadratu.
1 2 3
2 3 4
3 4 5
1. Wyszukiwanie kwadratu
Użyłbym wyszukiwania binarnego na przekątnej. Celem jest zlokalizowanie mniejszej liczby, która nie jest dokładnie niższa niż liczba docelowa.
Powiedzmy, że szukam na 4
przykład, a następnie zlokalizuję 5
w (2,2)
.
Następnie, jestem pewien, że jeśli 4
znajduje się w tabeli, to jest w położeniu, albo (x,2)
czy (2,x)
się x
w[0,2]
. Cóż, to tylko 2 wyszukiwania binarne.
Złożoność nie jest zniechęcająca: O(log(N))
(3 wyszukiwania binarne według zakresów długości N
)
2. Poszukiwanie prostokąta, naiwne podejście
Oczywiście trochę bardziej się komplikuje N
i M
różni się (prostokątem), rozważmy ten zdegenerowany przypadek:
1 2 3 4 5 6 7 8
2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17
I powiedzmy, że szukam 9
... Podejście ukośne jest nadal dobre, ale definicja diagonalnych się zmienia. Oto moja przekątna [1, (5 or 6), 17]
. Powiedzmy, że odebrałem [1,5,17]
, to wiem, że jeśli 9
jest w tabeli, to albo w podpunkcie:
5 6 7 8
6 7 8 9
10 11 12 13 14 15 16
To daje nam 2 prostokąty:
5 6 7 8 10 11 12 13 14 15 16
6 7 8 9
Więc możemy powtórzyć! prawdopodobnie zaczynając od tego z mniejszą liczbą elementów (choć w tym przypadku nas to zabija).
Powinienem zaznaczyć, że jeśli jeden z wymiarów jest mniejszy niż 3
, nie możemy zastosować metod diagonalnych i musimy użyć wyszukiwania binarnego. Tutaj oznaczałoby to:
- Zastosuj wyszukiwanie binarne do
10 11 12 13 14 15 16
, nie znaleziono
- Zastosuj wyszukiwanie binarne do
5 6 7 8
, nie znaleziono
- Zastosuj wyszukiwanie binarne do
6 7 8 9
, nie znaleziono
Jest to trudne, ponieważ aby uzyskać dobrą wydajność, możesz chcieć rozróżnić kilka przypadków, w zależności od ogólnego kształtu ...
3. Poszukiwanie prostokąta, brutalne podejście
Byłoby znacznie łatwiej, gdybyśmy mieli do czynienia z kwadratem ... więc po prostu wyrównajmy rzeczy.
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
Mamy teraz kwadrat.
Oczywiście prawdopodobnie NIE utworzymy tych wierszy, moglibyśmy je po prostu emulować.
def get(x,y):
if x < N and y < M: return table[x][y]
else: return table[N-1][M-1] # the max
więc zachowuje się jak kwadrat bez zajmowania większej ilości pamięci (kosztem szybkości pewnie w zależności od cache ... no cóż: p)
[[1 1][1 1]]
:?