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 4przykład, a następnie zlokalizuję 5w (2,2).
Następnie, jestem pewien, że jeśli 4znajduje się w tabeli, to jest w położeniu, albo (x,2)czy (2,x)się xw[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 Ni Mróż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 9jest 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]]:?