Подтвердить что ты не робот

Поиск ближайшего числа в диапазоне

Я подумал о следующей проблеме:

Мы имеем массив A целых чисел размера n, и у нас есть тестовые случаи t, и в каждом тестовом случае нам дано число m и диапазон [s, e], т.е. нам даны s и e, и нам нужно найти самое близкое число m в диапазоне этого массива (A [s] -A [e]).

Вы можете предположить, что индексируемые массивы от 1 до n.

Например:

  A = {5, 12, 9, 18, 19}
  m = 13
  s = 4 and e = 5

Итак, ответ должен быть 18.

Ограничения:

n<=10^5
t<=n

Все, что я думаю, - это решение O (n) для каждого тестового примера, и я думаю, что лучшее решение существует.

4b9b3361

Ответ 1

Это приблизительный эскиз: Создайте дерево сегментов из данных. В каждом node, помимо обычных данных, таких как левый и правый индексы, вы также сохраняете числа, найденные в поддереве, корневом в этом node, хранящемся в отсортированном порядке. Это можно достичь, когда вы построите дерево сегментов в порядке снизу вверх. В node прямо над листом вы сохраняете два значения листа в отсортированном порядке. В промежуточном node вы сохраняете числа в левом дочернем элементе и правом дочернем элементе, с которым вы можете объединиться, используя стандартное слияние. В дереве есть O (n) узлы, и для сохранения этих данных требуется общая O (nlog (n)).

Когда у вас есть это дерево, для каждого запроса пройдите по пути, пока не достигнете соответствующего node (s) в заданном диапазоне ([s, e]). Как показано в учебнике, один или несколько разных узлов объединяются для формирования заданного диапазона. Поскольку глубина дерева равна O (log (n)), это время для каждого запроса для достижения этих узлов. Каждый запрос должен быть O (log (n)). Для всех узлов, которые полностью находятся внутри диапазона, найдите ближайший номер, используя двоичный поиск в отсортированном массиве, хранящемся в этих узлах. Опять же, O (log (n)). Найдите ближайшего из всех этих, и это ответ. Таким образом, вы можете ответить на каждый запрос в O (log (n)) времени.

В учебнике, в котором я ссылаюсь, содержатся другие структуры данных, такие как разреженная таблица, которые проще реализовать, и должны давать O (sqrt (n)) для каждого запроса. Но я об этом не думал.

Ответ 2

Я уверен, что не существует более быстрого решения. Небольшая вариация вашей проблемы:

Нет массива A, но каждый тестовый пример содержит несортированный массив чисел для поиска. (Массивный срез A от s до e).

В этом случае, очевидно, нет лучшего способа, чем линейный поиск для каждого тестового примера.

Теперь, какова ваша оригинальная проблема, более конкретная, чем вариация выше? Единственная добавленная информация состоит в том, что все срезы поступают из одного массива. Я не думаю, что это дополнительное ограничение может быть использовано для алгоритмического ускорения.

ИЗМЕНИТЬ: Я стою исправлено. Структура данных дерева сегментов должна работать.

Ответ 3

сортировать массив и выполнять двоичный поиск. сложность: o (nlogn + logn * t)