mirror of
https://github.com/krahets/hello-algo.git
synced 2026-08-26 18:17:13 +00:00
deploy
This commit is contained in:
@@ -39,7 +39,7 @@
|
||||
|
||||
|
||||
|
||||
<title>12.2 Поисковая стратегия divide and conquer - Hello Algo</title>
|
||||
<title>12.2 Поисковая стратегия разделяй и властвуй - Hello Algo</title>
|
||||
|
||||
|
||||
|
||||
@@ -65,8 +65,8 @@
|
||||
|
||||
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Noto+Sans:300,300i,400,400i,500,500i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
|
||||
<style>:root{--md-text-font:"Noto Sans";--md-code-font:"JetBrains Mono"}</style>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=PT+Sans:300,300i,400,400i,500,500i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
|
||||
<style>:root{--md-text-font:"PT Sans";--md-code-font:"JetBrains Mono"}</style>
|
||||
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
<div data-md-component="skip">
|
||||
|
||||
|
||||
<a href="#122-divide-and-conquer" class="md-skip">
|
||||
<a href="#122" class="md-skip">
|
||||
Перейти к содержанию
|
||||
</a>
|
||||
|
||||
@@ -152,7 +152,7 @@
|
||||
<div class="md-header__topic" data-md-component="header-topic">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
12.2 Поисковая стратегия divide and conquer
|
||||
12.2 Поисковая стратегия разделяй и властвуй
|
||||
|
||||
</span>
|
||||
</div>
|
||||
@@ -574,7 +574,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 1. Знакомство с алгоритмами
|
||||
Глава 1. Введение в алгоритмы
|
||||
|
||||
|
||||
|
||||
@@ -596,7 +596,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 1. Знакомство с алгоритмами
|
||||
Глава 1. Введение в алгоритмы
|
||||
|
||||
|
||||
</label>
|
||||
@@ -646,7 +646,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
1.2 Что такое структуры данных и алгоритмы
|
||||
1.2 Что такое алгоритм
|
||||
|
||||
|
||||
|
||||
@@ -1181,7 +1181,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 4. Массив и связный список
|
||||
Глава 4. Массивы и списки
|
||||
|
||||
|
||||
|
||||
@@ -1203,7 +1203,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 4. Массив и связный список
|
||||
Глава 4. Массивы и списки
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1309,7 +1309,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
4.4 Память и кеш *
|
||||
4.4 Оперативная память и кэш *
|
||||
|
||||
|
||||
|
||||
@@ -1591,7 +1591,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 6. Хеширование
|
||||
Глава 6. Хеш-таблицы
|
||||
|
||||
|
||||
|
||||
@@ -1613,7 +1613,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 6. Хеширование
|
||||
Глава 6. Хеш-таблицы
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1691,7 +1691,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
6.3 Хеш-алгоритмы
|
||||
6.3 Алгоритмы хеширования
|
||||
|
||||
|
||||
|
||||
@@ -1786,7 +1786,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 7. Дерево
|
||||
Глава 7. Деревья
|
||||
|
||||
|
||||
|
||||
@@ -1808,7 +1808,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 7. Дерево
|
||||
Глава 7. Деревья
|
||||
|
||||
|
||||
</label>
|
||||
@@ -1886,7 +1886,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
7.3 Представление дерева массивом
|
||||
7.3 Представление двоичного дерева массивом
|
||||
|
||||
|
||||
|
||||
@@ -1970,7 +1970,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
7.6 Резюме
|
||||
7.6 Краткие итоги
|
||||
|
||||
|
||||
|
||||
@@ -2133,7 +2133,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
8.3 Задача Top-K
|
||||
8.3 Задача Top-k
|
||||
|
||||
|
||||
|
||||
@@ -2224,7 +2224,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
Глава 9. Граф
|
||||
Глава 9. Графы
|
||||
|
||||
|
||||
|
||||
@@ -2246,7 +2246,7 @@
|
||||
<span class="md-nav__icon md-icon"></span>
|
||||
|
||||
|
||||
Глава 9. Граф
|
||||
Глава 9. Графы
|
||||
|
||||
|
||||
</label>
|
||||
@@ -2296,7 +2296,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
9.2 Базовые операции над графами
|
||||
9.2 Базовые операции графа
|
||||
|
||||
|
||||
|
||||
@@ -2352,7 +2352,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
9.4 Резюме
|
||||
9.4 Краткие итоги
|
||||
|
||||
|
||||
|
||||
@@ -2491,7 +2491,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.2 Точка вставки двоичного поиска
|
||||
10.2 Двоичный поиск точки вставки
|
||||
|
||||
|
||||
|
||||
@@ -2519,7 +2519,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.3 Граничные случаи двоичного поиска
|
||||
10.3 Двоичный поиск границ
|
||||
|
||||
|
||||
|
||||
@@ -2547,7 +2547,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.4 Стратегия оптимизации через хеширование
|
||||
10.4 Стратегии оптимизации хеширования
|
||||
|
||||
|
||||
|
||||
@@ -2575,7 +2575,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
10.5 Алгоритмы поиска: новый взгляд
|
||||
10.5 Переосмысление алгоритмов поиска
|
||||
|
||||
|
||||
|
||||
@@ -2780,7 +2780,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.3 Пузырьковая сортировка
|
||||
11.3 Сортировка пузырьком
|
||||
|
||||
|
||||
|
||||
@@ -2808,7 +2808,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
11.4 Сортировка вставкой
|
||||
11.4 Сортировка вставками
|
||||
|
||||
|
||||
|
||||
@@ -3115,7 +3115,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.1 Алгоритмы разделяй и властвуй
|
||||
12.1 Стратегия разделяй и властвуй
|
||||
|
||||
|
||||
|
||||
@@ -3152,7 +3152,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.2 Стратегия поиска разделяй и властвуй
|
||||
12.2 Поисковая стратегия разделяй и властвуй
|
||||
|
||||
|
||||
|
||||
@@ -3170,7 +3170,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
12.2 Стратегия поиска разделяй и властвуй
|
||||
12.2 Поисковая стратегия разделяй и властвуй
|
||||
|
||||
|
||||
|
||||
@@ -3197,10 +3197,10 @@
|
||||
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#1-divide-and-conquer" class="md-nav__link">
|
||||
<a href="#1" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
1. Реализация двоичного поиска на основе divide and conquer
|
||||
1. Реализация двоичного поиска на основе "разделяй и властвуй"
|
||||
|
||||
</span>
|
||||
</a>
|
||||
@@ -3479,7 +3479,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
13.4 Задача о $n$ ферзях
|
||||
13.4 Задача о n ферзях
|
||||
|
||||
|
||||
|
||||
@@ -3620,7 +3620,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.1 Введение в динамическое программирование
|
||||
14.1 Первое знакомство с динамическим программированием
|
||||
|
||||
|
||||
|
||||
@@ -3732,7 +3732,7 @@
|
||||
<span class="md-ellipsis">
|
||||
|
||||
|
||||
14.5 Задача о неограниченном рюкзаке
|
||||
14.5 Задача о полном рюкзаке
|
||||
|
||||
|
||||
|
||||
@@ -4285,10 +4285,10 @@
|
||||
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
|
||||
|
||||
<li class="md-nav__item">
|
||||
<a href="#1-divide-and-conquer" class="md-nav__link">
|
||||
<a href="#1" class="md-nav__link">
|
||||
<span class="md-ellipsis">
|
||||
|
||||
1. Реализация двоичного поиска на основе divide and conquer
|
||||
1. Реализация двоичного поиска на основе "разделяй и властвуй"
|
||||
|
||||
</span>
|
||||
</a>
|
||||
@@ -4332,40 +4332,40 @@
|
||||
|
||||
|
||||
<!-- Page content -->
|
||||
<h1 id="122-divide-and-conquer">12.2 Поисковая стратегия divide and conquer<a class="headerlink" href="#122-divide-and-conquer" title="Permanent link">¶</a></h1>
|
||||
<h1 id="122">12.2 Поисковая стратегия разделяй и властвуй<a class="headerlink" href="#122" title="Permanent link">¶</a></h1>
|
||||
<p>Мы уже знаем, что алгоритмы поиска делятся на две большие категории.</p>
|
||||
<ul>
|
||||
<li><strong>Полный перебор</strong>: реализуется через обход структуры данных, временная сложность равна <span class="arithmatex">\(O(n)\)</span> .</li>
|
||||
<li><strong>Адаптивный поиск</strong>: использует особую организацию данных или априорную информацию, временная сложность может достигать <span class="arithmatex">\(O(\log n)\)</span> и даже <span class="arithmatex">\(O(1)\)</span> .</li>
|
||||
</ul>
|
||||
<p>На практике <strong>алгоритмы поиска с временной сложностью <span class="arithmatex">\(O(\log n)\)</span> обычно реализуются на основе стратегии divide and conquer</strong>, например двоичный поиск и деревья.</p>
|
||||
<p>На практике <strong>алгоритмы поиска с временной сложностью <span class="arithmatex">\(O(\log n)\)</span> обычно реализуются на основе стратегии "разделяй и властвуй"</strong>, например двоичный поиск и деревья.</p>
|
||||
<ul>
|
||||
<li>На каждом шаге двоичный поиск раскладывает задачу (поиск целевого элемента в массиве) на более мелкую задачу (поиск целевого элемента в одной половине массива), и этот процесс продолжается, пока массив не станет пустым или пока не будет найден целевой элемент.</li>
|
||||
<li>Деревья являются типичными представителями идей divide and conquer; в таких структурах данных, как двоичное дерево поиска, AVL-дерево и куча, временная сложность различных операций равна <span class="arithmatex">\(O(\log n)\)</span> .</li>
|
||||
<li>Деревья являются типичными представителями идей "разделяй и властвуй"; в таких структурах данных, как двоичное дерево поиска, AVL-дерево и куча, временная сложность различных операций равна <span class="arithmatex">\(O(\log n)\)</span> .</li>
|
||||
</ul>
|
||||
<p>Стратегия divide and conquer для двоичного поиска выглядит следующим образом.</p>
|
||||
<p>Стратегия "разделяй и властвуй" для двоичного поиска выглядит следующим образом.</p>
|
||||
<ul>
|
||||
<li><strong>Задача раскладывается на части</strong>: двоичный поиск рекурсивно разбивает исходную задачу (поиск в массиве) на подзадачу (поиск в одной половине массива), и это достигается сравнением среднего элемента с целевым значением.</li>
|
||||
<li><strong>Подзадачи независимы</strong>: в двоичном поиске на каждом шаге обрабатывается только одна подзадача, и она не зависит от других подзадач.</li>
|
||||
<li><strong>Решения подзадач не нужно объединять</strong>: двоичный поиск нацелен на поиск конкретного элемента, поэтому объединять решения подзадач не требуется. Как только подзадача решена, одновременно считается решенной и исходная задача.</li>
|
||||
</ul>
|
||||
<p>По сути divide and conquer повышает эффективность поиска потому, что при полном переборе за один шаг удается исключить только один вариант, <strong>тогда как при поиске на основе divide and conquer за один шаг можно исключить половину вариантов</strong>.</p>
|
||||
<h3 id="1-divide-and-conquer">1. Реализация двоичного поиска на основе divide and conquer<a class="headerlink" href="#1-divide-and-conquer" title="Permanent link">¶</a></h3>
|
||||
<p>В предыдущих главах двоичный поиск реализовывался через итерацию. Теперь реализуем его с помощью divide and conquer, то есть через рекурсию.</p>
|
||||
<p>Иными словами, стратегия "разделяй и властвуй" повышает эффективность поиска потому, что при полном переборе за один шаг удается исключить только один вариант, <strong>тогда как при поиске на основе "разделяй и властвуй" за один шаг можно исключить половину вариантов</strong>.</p>
|
||||
<h3 id="1">1. Реализация двоичного поиска на основе "разделяй и властвуй"<a class="headerlink" href="#1" title="Permanent link">¶</a></h3>
|
||||
<p>В предыдущих главах двоичный поиск реализовывался через итерацию. Теперь реализуем его с помощью стратегии "разделяй и властвуй", то есть через рекурсию.</p>
|
||||
<div class="admonition question">
|
||||
<p class="admonition-title">Question</p>
|
||||
<p>Дан отсортированный массив <code>nums</code> длины <span class="arithmatex">\(n\)</span> , в котором все элементы уникальны. Найдите элемент <code>target</code> .</p>
|
||||
</div>
|
||||
<p>С точки зрения divide and conquer обозначим подзадачу, соответствующую интервалу поиска <span class="arithmatex">\([i, j]\)</span> , через <span class="arithmatex">\(f(i, j)\)</span> .</p>
|
||||
<p>С точки зрения стратегии "разделяй и властвуй" обозначим подзадачу, соответствующую интервалу поиска <span class="arithmatex">\([i, j]\)</span> , через <span class="arithmatex">\(f(i, j)\)</span> .</p>
|
||||
<p>Начиная с исходной задачи <span class="arithmatex">\(f(0, n-1)\)</span> , выполняем двоичный поиск по следующим шагам.</p>
|
||||
<ol>
|
||||
<li>Вычислить середину <span class="arithmatex">\(m\)</span> интервала поиска <span class="arithmatex">\([i, j]\)</span> и с ее помощью исключить половину интервала.</li>
|
||||
<li>Рекурсивно решить подзадачу вдвое меньшего размера; это может быть либо <span class="arithmatex">\(f(i, m-1)\)</span> , либо <span class="arithmatex">\(f(m+1, j)\)</span> .</li>
|
||||
<li>Повторять шаг <code>1.</code> и шаг <code>2.</code> , пока не будет найден <code>target</code> или пока интервал не станет пустым.</li>
|
||||
</ol>
|
||||
<p>На рисунке 12-4 показан процесс применения divide and conquer для поиска элемента <span class="arithmatex">\(6\)</span> в массиве.</p>
|
||||
<p><img alt="Процесс двоичного поиска в стиле divide and conquer" class="animation-figure" src="../binary_search_recur.assets/binary_search_recur.png" /></p>
|
||||
<p align="center"> Рисунок 12-4 Процесс двоичного поиска в стиле divide and conquer </p>
|
||||
<p>На рисунке 12-4 показан процесс применения стратегии "разделяй и властвуй" для поиска элемента <span class="arithmatex">\(6\)</span> в массиве.</p>
|
||||
<p><img alt="Процесс двоичного поиска в стиле разделяй и властвуй" class="animation-figure" src="../binary_search_recur.assets/binary_search_recur.png" /></p>
|
||||
<p align="center"> Рисунок 12-4 Процесс двоичного поиска в стиле разделяй и властвуй </p>
|
||||
|
||||
<p>В реализации кода мы объявляем рекурсивную функцию <code>dfs()</code> для решения задачи <span class="arithmatex">\(f(i, j)\)</span> :</p>
|
||||
<div class="tabbed-set tabbed-alternate" data-tabs="1:13"><input checked="checked" id="__tabbed_1_1" name="__tabbed_1" type="radio" /><input id="__tabbed_1_2" name="__tabbed_1" type="radio" /><input id="__tabbed_1_3" name="__tabbed_1" type="radio" /><input id="__tabbed_1_4" name="__tabbed_1" type="radio" /><input id="__tabbed_1_5" name="__tabbed_1" type="radio" /><input id="__tabbed_1_6" name="__tabbed_1" type="radio" /><input id="__tabbed_1_7" name="__tabbed_1" type="radio" /><input id="__tabbed_1_8" name="__tabbed_1" type="radio" /><input id="__tabbed_1_9" name="__tabbed_1" type="radio" /><input id="__tabbed_1_10" name="__tabbed_1" type="radio" /><input id="__tabbed_1_11" name="__tabbed_1" type="radio" /><input id="__tabbed_1_12" name="__tabbed_1" type="radio" /><input id="__tabbed_1_13" name="__tabbed_1" type="radio" /><div class="tabbed-labels"><label for="__tabbed_1_1">Python</label><label for="__tabbed_1_2">C++</label><label for="__tabbed_1_3">Java</label><label for="__tabbed_1_4">C#</label><label for="__tabbed_1_5">Go</label><label for="__tabbed_1_6">Swift</label><label for="__tabbed_1_7">JS</label><label for="__tabbed_1_8">TS</label><label for="__tabbed_1_9">Dart</label><label for="__tabbed_1_10">Rust</label><label for="__tabbed_1_11">C</label><label for="__tabbed_1_12">Kotlin</label><label for="__tabbed_1_13">Ruby</label></div>
|
||||
@@ -4777,7 +4777,7 @@ aria-label="Нижний колонтитул"
|
||||
<a
|
||||
href="../divide_and_conquer/"
|
||||
class="md-footer__link md-footer__link--prev"
|
||||
aria-label="Назад: 12.1 Алгоритмы разделяй и властвуй"
|
||||
aria-label="Назад: 12.1 Стратегия разделяй и властвуй"
|
||||
rel="prev"
|
||||
>
|
||||
<div class="md-footer__button md-icon">
|
||||
@@ -4789,7 +4789,7 @@ aria-label="Нижний колонтитул"
|
||||
Назад
|
||||
</span>
|
||||
<div class="md-ellipsis">
|
||||
12.1 Алгоритмы разделяй и властвуй
|
||||
12.1 Стратегия разделяй и властвуй
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
Reference in New Issue
Block a user