Вот простой подход:
- Начните с нижнего левого угла.
- Если цель меньше этого значения, она должна быть выше нас, поэтому поднимитесь на 1 .
- В противном случае мы знаем, что цель не может быть в этомстолбец, поэтому переместить вправо на один .
- Перейти к 2.
Для массива NxM
это выполняется в O(N+M)
.Я думаю, что было бы трудно сделать лучше.:)
Редактировать: Много хорошего обсуждения.Я говорил об общем случае выше;ясно, что если N
или M
малы, вы можете использовать подход двоичного поиска, чтобы сделать это во время, приближающемся к логарифмическому времени.
Вот некоторые подробности для любопытных:
History
Этот простой алгоритм называется Saddleback Search .Это было вокруг некоторое время, и это оптимально, когда N == M
.Некоторые ссылки:
Однако, когда N < M
, интуиция предполагает, что бинарный поиск должен работать лучше, чем O(N+M)
: например, когда N == 1
, чистый двоичный поиск будет выполняться в логарифмическом, а не линейном времени.
Наихудший предел
Ричард Берд исследовал эту интуицию, согласно которой двоичный поиск может улучшить алгоритм Saddleback в статье 2006 года:
Используя довольно необычную диалоговую технику, Берд показывает нам, что для N <= M
эта проблема имеет нижнюю границу Ω(N * log(M/N))
.Эта граница имеет смысл, поскольку она дает нам линейную производительность при N == M
и логарифмическую производительность при N == 1
.
Алгоритмы для прямоугольных массивов
Один подход, использующий строковый двоичный файлпоиск выглядит так:
- Начните с прямоугольного массива, где
N < M
.Допустим, N
это строки, а M
это столбцы. - Выполните двоичный поиск в средней строке для
value
.Если мы найдем его, мы закончим. - В противном случае мы нашли соседнюю пару чисел
s
и g
, где s < value < g
. - Прямоугольник чисел вышеи слева от
s
меньше value
, поэтому мы можем устранить его. - Прямоугольник ниже и справа от
g
больше value
, поэтому мы можем устранить его. - Переходите к шагу (2) для каждого из двух оставшихся прямоугольников.
С точки зрения сложности наихудшего случая этот алгоритм log(M)
работает для устранения половины возможныхрешения, а затем рекурсивно вызывает себя дважды на две меньшие проблемы.Нам нужно повторить уменьшенную версию этой log(M)
работы для каждой строки, , но если количество строк мало по сравнению с количеством столбцов, то возможность удалить все эти столбцы в логарифмическом времени начинаетстать стоящим .
Это придает алгоритму сложность T(N,M) = log(M) + 2 * T(M/2, N/2)
, что, как показывает Птица, составляет O(N * log(M/N))
.
Другой подход, опубликованный Крейгом Гидни описывает алгоритм, подобный подходу выше: он проверяет строку за раз, используя размер шага M/N
.Его анализ показывает, что это также приводит к производительности O(N * log(M/N))
.
Сравнение производительности
Анализ Big-O - это хорошо, но насколько хорошо эти подходы работают на практике?В приведенной ниже таблице рассматриваются четыре алгоритма для все более «квадратных» массивов:
(«Наивный» алгоритм просто ищет каждый элемент массива. «Рекурсивный» алгоритм описан выше. «Гибридный» алгоритм представляет собой реализацию алгоритма Гидни . Для каждого размера массива производительность был измерен путем синхронизации каждого алгоритма с фиксированным набором из 1 000 000 случайно сгенерированных массивов.)
Некоторые заметные моменты:
- Как и ожидалось, алгоритмы «двоичного поиска» обеспечивают лучшую производительность для прямоугольных массивов, а алгоритм Saddleback лучше всего работает для квадратных массивов.
- Алгоритм Saddleback работает хуже, чем «наивный» алгоритм для 1-мерных массивов, предположительно потому, что он выполняет несколько сравнений для каждого элемента.
- Падение производительности, которое алгоритмы «двоичного поиска» принимают для квадратных массивов, по-видимому, связано с накладными расходами на выполнение повторных двоичных поисков.
Резюме
Умное использование бинарного поиска может обеспечить производительность O(N * log(M/N)
как для прямоугольных, так и для квадратных массивов. Алгоритм O(N + M)
«Седло» намного проще, но страдает от снижения производительности, так как массивы становятся все более прямоугольными.