Eh bien, pour commencer, supposons que nous utilisons un carré.
1 2 3
2 3 4
3 4 5
1. Recherche d'un carré
J'utiliserais une recherche binaire sur la diagonale. L'objectif est de localiser le plus petit nombre qui n'est pas strictement inférieur au nombre cible.
Disons que je cherche 4, par exemple, je finirais localiser 5à (2,2).
Ensuite, je suis assuré que si 4est dans le tableau, il est à une position soit (x,2)ou (2,x)avec xdans[0,2] . Eh bien, ce n'est que 2 recherches binaires.
La complexité n'est pas décourageante: O(log(N))(3 recherches binaires sur des plages de longueurN )
2. Recherche d'un rectangle, approche naïve
Bien sûr, cela devient un peu plus compliqué quand Net Mdifférer (avec un rectangle), considérez ce cas dégénéré:
1 2 3 4 5 6 7 8
2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17
Et disons que je cherche 9... L'approche diagonale est toujours bonne, mais la définition des changements diagonaux. Voici ma diagonale [1, (5 or 6), 17]. Disons que j'ai ramassé [1,5,17], alors je sais que si 9est dans le tableau, c'est soit dans la sous-partie:
5 6 7 8
6 7 8 9
10 11 12 13 14 15 16
Cela nous donne 2 rectangles:
5 6 7 8 10 11 12 13 14 15 16
6 7 8 9
Alors on peut récurer! probablement en commençant par celui avec le moins d'éléments (bien que dans ce cas, cela nous tue).
Je dois souligner que si l'une des dimensions est inférieure à 3, nous ne pouvons pas appliquer les méthodes diagonales et devons utiliser une recherche binaire. Ici, cela signifierait:
- Appliquer la recherche binaire sur
10 11 12 13 14 15 16, non trouvé
- Appliquer la recherche binaire sur
5 6 7 8, non trouvé
- Appliquer la recherche binaire sur
6 7 8 9, non trouvé
C'est délicat car pour obtenir de bonnes performances, vous voudrez peut-être différencier plusieurs cas, en fonction de la forme générale ...
3. Recherche d'un rectangle, approche brutale
Ce serait beaucoup plus facile si nous nous occupions d'un carré ... alors concilions les choses.
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
Nous avons maintenant un carré.
Bien sûr, nous ne créerons probablement PAS réellement ces lignes, nous pourrions simplement les émuler.
def get(x,y):
if x < N and y < M: return table[x][y]
else: return table[N-1][M-1] # the max
donc ça se comporte comme un carré sans occuper plus de mémoire (au prix de la vitesse, probablement, en fonction du cache ... eh bien: p)
[[1 1][1 1]]:?