5.4 KiB
Стратегия поиска «разделяй и властвуй»
Мы уже знаем, что алгоритмы поиска делятся на две большие категории.
-
Полный перебор: реализуется путем обхода структуры данных, временная сложность составляет O(n).
-
Адаптивный поиск: использует особую организацию данных или априорную информацию, временная сложность может достигать O(log n) или даже O(1).
На практике алгоритмы поиска с временной сложностью O(log n) обычно реализуются на основе стратегии «разделяй и властвуй», например двоичный поиск и деревья.
-
Двоичный поиск на каждом шаге разбивает задачу (поиск целевого элемента в массиве) на более мелкую задачу (поиск целевого элемента в половине массива). Этот процесс продолжается до тех пор, пока массив не станет пустым или не будет найден целевой элемент.
-
Деревья являются представителями стратегии «разделяй и властвуй». В структурах данных, таких как двоичное дерево поиска, АВЛ-дерево, куча и др., временная сложность различных операций составляет O(log n).
Стратегия «разделяй и властвуй» для двоичного поиска выглядит следующим образом.
-
Задачу можно разбить: двоичный поиск рекурсивно разбивает исходную задачу (поиск в массиве) на подзадачи (поиск в половине массива), что достигается сравнением среднего элемента с целевым элементом.
-
Подзадачи независимы: в двоичном поиске на каждом этапе обрабатывается только одна подзадача, которая не зависит от других подзадач.
-
Решения подзадач не требуют объединения: двоичный поиск направлен на поиск конкретного элемента, поэтому объединять решения подзадач не требуется. Когда подзадача решена, исходная задача также считается решенной.
Стратегия «разделяй и властвуй» повышает эффективность поиска, поскольку при грубом поиске на каждом этапе можно исключить только один вариант, тогда как при поиске «разделяй и властвуй» на каждом этапе можно исключить половину вариантов.
Реализация двоичного поиска на основе стратегии «разделяй и властвуй»
В предыдущих главах двоичный поиск был реализован на основе итераций. Теперь мы реализуем его на основе принципа «разделяй и властвуй» (рекурсии).
!!! question
Дан упорядоченный массив `nums` длиной $n$, в котором все элементы уникальны. Необходимо найти элемент `target`.
Для применения стратегии «разделяй и властвуй» обозначим подзадачу для поискового интервала [i, j] как f(i, j).
Начав с исходной задачи f(0, n - 1), выполняем двоичный поиск по следующему алгоритму:
- Вычисление средней точки
mпоискового интервала[i, j]и исключение половины интервала на основе сравнения со средним элементом. - Рекурсивное решение подзадачи с уменьшенным вдвое размером, возможны варианты
f(i, m - 1)иf(m + 1, j). - Повторение шагов
1.и2.до тех пор, пока не будет найден элементtargetили интервал не станет пустым.
На рис. 12.4 иллюстрируется процесс применения стратегии «разделяй и властвуй» при двоичном поиске элемента 6 в массиве.
В коде реализации объявляется рекурсивная функция dfs() для решения задачи f(i, j):
[file]{binary_search_recur}-[class]{}-[func]{binary_search}
