Ну, для початку припустимо, що ми використовуємо квадрат.
1 2 3
2 3 4
3 4 5
1. Пошук квадрата
Я б використав двійковий пошук по діагоналі. Мета - знайти меншу кількість, яка не є строго нижчою за цільову.
Скажімо, я шукаю, 4наприклад, тоді я в кінцевому підсумку знайду 5в (2,2).
Тоді, я впевнений , що якщо 4в таблиці, знаходиться в положенні або (x,2)або (2,x)з xв [0,2]. Ну, це лише 2 двійкові пошукові запити.
Складність не лякає: O(log(N))(3 двійкові пошуки за діапазонами довжини N)
2. Пошук прямокутника, наївний підхід
Звичайно, стає дещо складніше, коли Nі Mвідрізняються (за допомогою прямокутника), розглянемо цей вироджений випадок:
1 2 3 4 5 6 7 8
2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17
І скажімо, я шукаю 9... Діагональний підхід все ще хороший, але визначення діагональних змін. Ось моя діагональ [1, (5 or 6), 17]. Скажімо, я взяв [1,5,17], тоді я знаю, що якщо 9є в таблиці, це або в підрозділі:
5 6 7 8
6 7 8 9
10 11 12 13 14 15 16
Це дає нам 2 прямокутники:
5 6 7 8 10 11 12 13 14 15 16
6 7 8 9
Тож ми можемо повторити! можливо, починаючи з того, що має менше елементів (хоча в цьому випадку це вбиває нас).
Слід зазначити, що якщо один із вимірів менше 3, ми не можемо застосовувати діагональні методи і повинні використовувати двійковий пошук. Тут це означало б:
- Застосувати двійковий пошук
10 11 12 13 14 15 16, не знайдено
- Застосувати двійковий пошук
5 6 7 8, не знайдено
- Застосувати двійковий пошук
6 7 8 9, не знайдено
Це складно, тому що для отримання хороших показників ви можете розрізняти кілька випадків, залежно від загальної форми ....
3. Пошук у прямокутнику, жорстокий підхід
Було б набагато простіше, якби ми мали справу з квадратом ... тож давайте просто вирівняємо речі.
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
Зараз у нас є квадрат.
Звичайно, ми, мабуть, фактично НЕ будемо створювати ці рядки, ми могли б просто наслідувати їх.
def get(x,y):
if x < N and y < M: return table[x][y]
else: return table[N-1][M-1] # the max
тому він поводиться як квадрат, не займаючи більше пам'яті (ціною швидкості, мабуть, залежно від кеш-пам'яті ... ну добре: p)
[[1 1][1 1]]:?