mirror of
https://github.com/krahets/hello-algo.git
synced 2026-08-10 11:00:59 +00:00
First version.
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
# Стратегия поиска «разделяй и властвуй»
|
||||
|
||||
Мы уже знаем, что алгоритмы поиска делятся на две большие категории.
|
||||
|
||||
- **Полный перебор**: реализуется путем обхода структуры данных, временная сложность составляет *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)$, выполняем двоичный поиск по следующему алгоритму:
|
||||
|
||||
1. Вычисление средней точки $m$ поискового интервала $[i, j]$ и исключение половины интервала на основе сравнения со средним элементом.
|
||||
2. Рекурсивное решение подзадачи с уменьшенным вдвое размером, возможны варианты $f(i, m - 1)$ и $f(m + 1, j)$.
|
||||
3. Повторение шагов `1.` и `2.` до тех пор, пока не будет найден элемент `target` или интервал не станет пустым.
|
||||
|
||||
На рис. 12.4 иллюстрируется процесс применения стратегии «разделяй и властвуй» при двоичном поиске элемента 6 в массиве.
|
||||
|
||||

|
||||
|
||||
В коде реализации объявляется рекурсивная функция `dfs()` для решения задачи $f(i, j)$:
|
||||
|
||||
```src
|
||||
[file]{binary_search_recur}-[class]{}-[func]{binary_search}
|
||||
```
|
||||
Reference in New Issue
Block a user