mirror of
https://github.com/krahets/hello-algo.git
synced 2026-07-22 03:16:08 +00:00
Add translated chapter exercise pages (#1941)
Add dedicated chapter exercise sections and generated exercise pages for the English, Japanese, and Russian editions. Add navigation for all published languages while keeping Taiwan Traditional Chinese exercise pages generated at build time.
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
<!-- Автоматически создано utils/exercises/publish_exercises.py; не редактируйте напрямую. -->
|
||||
|
||||
# Упражнения
|
||||
|
||||
## Вопросы для самопроверки
|
||||
|
||||
### Что первым извлекается из стека и очереди
|
||||
|
||||
Подготовьте пустой стек `S` и пустую очередь `Q`, а затем выполните с каждым из них один и тот же набор операций:
|
||||
|
||||
шаг 1: добавить `A`;
|
||||
шаг 2: добавить `B`;
|
||||
шаг 3: удалить один элемент и записать его;
|
||||
шаг 4: добавить `C`;
|
||||
шаг 5: удалять и записывать элементы, пока контейнер не опустеет.
|
||||
|
||||
Запишите порядок удаления элементов из `S` и `Q`. Объясните различие принципами «последним пришел — первым вышел» и «первым пришел — первым вышел».
|
||||
|
||||
??? success "Ответ"
|
||||
|
||||
Порядок удаления из стека `S`: `B, C, A`. После добавления `A, B` первым извлекается последний добавленный элемент `B`; затем добавляется `C`,
|
||||
после чего извлекаются `C, A`. Это принцип «последним пришел — первым вышел».
|
||||
|
||||
Порядок удаления из очереди `Q`: `A, B, C`. После добавления `A, B` первым удаляется самый ранний элемент `A`;
|
||||
затем добавляется `C`, после чего удаляются `B, C`. Это принцип «первым пришел — первым вышел».
|
||||
|
||||
### Что происходит, когда хвост очереди проходит конец массива
|
||||
|
||||
Очередь реализована с помощью кольцевого массива длины 5 с индексами `0–4`.
|
||||
Сейчас `front = 3`, `size = 2`, а элементы очереди `A, B` находятся по индексам 3 и 4 соответственно.
|
||||
|
||||
<!-- numbered-subquestions -->
|
||||
|
||||
1. По какому индексу нужно поместить `C` при операции «добавить `C` в очередь»? Чему после этого равно `size`?
|
||||
2. Затем из очереди удаляется один элемент. Какой именно? Чему равны новые значения `front` и `size`?
|
||||
3. Каков теперь логический порядок элементов от головы к хвосту очереди? Нужно ли при удалении сдвигать остальные элементы массива и почему?
|
||||
|
||||
??? success "Ответ"
|
||||
|
||||
1. Позиция нового элемента равна
|
||||
`(front + size) % 5 = (3 + 2) % 5 = 0`,
|
||||
поэтому `C` помещается по индексу 0. После добавления `size = 3`.
|
||||
|
||||
2. Из очереди удаляется текущий первый элемент `A`. Новый индекс головы равен
|
||||
`(3 + 1) % 5 = 4`, поэтому `front = 4`, `size = 2`.
|
||||
|
||||
3. Логический порядок находящихся в очереди элементов — `B, C`: `B` находится по индексу 4, а `C` — по индексу 0.
|
||||
При удалении достаточно изменить `front` и `size`. Благодаря остатку от деления индекс в кольцевом массиве возвращается к началу,
|
||||
поэтому сдвигать вперед все остальные элементы не нужно.
|
||||
|
||||
### Операции с обоих концов двусторонней очереди
|
||||
|
||||
Здесь `push_first` означает добавление в голову, `push_last` — добавление в хвост,
|
||||
`pop_first` — извлечение из головы, а `pop_last` — извлечение из хвоста.
|
||||
|
||||
С пустой двусторонней очередью `deq` последовательно выполняются операции:
|
||||
|
||||
1. `push_last(A)`
|
||||
2. `push_last(B)`
|
||||
3. `push_first(C)`
|
||||
4. `pop_last()`
|
||||
5. `push_last(D)`
|
||||
6. `pop_first()`
|
||||
|
||||
<!-- numbered-subquestions -->
|
||||
|
||||
1. Какие элементы возвращают две операции извлечения?
|
||||
2. Какие элементы остаются после всех операций в порядке от головы к хвосту?
|
||||
3. Рассмотрите все 6 шагов. Можно ли выполнить их с обычной очередью, в которую разрешено добавлять только с хвоста, а удалять только с головы? Если нет, укажите недопустимые операции. Объясните также, может ли выполнить все шаги двусторонняя очередь и почему.
|
||||
|
||||
??? success "Ответ"
|
||||
|
||||
После первых трех шагов двусторонняя очередь от головы к хвосту имеет вид `[C, A, B]`.
|
||||
|
||||
<!-- numbered-subquestions -->
|
||||
|
||||
1. `pop_last()` возвращает `B`. После добавления `D` очередь имеет вид `[C, A, D]`,
|
||||
а `pop_first()` возвращает `C`.
|
||||
|
||||
2. В конце остаются `[A, D]`.
|
||||
|
||||
3. Обычная очередь, допускающая добавление с хвоста и удаление с головы, не может выполнить все операции:
|
||||
шаг 3 `push_first(C)` требует добавить элемент с головы, а шаг 4 `pop_last()` — удалить элемент с хвоста. Обе операции выходят за рамки обычной очереди.
|
||||
Двусторонняя очередь позволяет добавлять и удалять элементы с обоих концов, поэтому может выполнить все 6 шагов.
|
||||
|
||||
## Задачи по программированию
|
||||
|
||||
### Проверка последовательности скобок
|
||||
|
||||
Дана строка `s`, содержащая только скобки трех видов: `()`, `[]`, `{}`. С помощью стека определите, является ли последовательность правильной.
|
||||
|
||||
Правильная последовательность должна удовлетворять двум условиям: каждая закрывающая скобка соответствует по виду ближайшей еще не сопоставленной открывающей скобке,
|
||||
а после обхода не остается несопоставленных открывающих скобок. Верните логическое значение результата проверки.
|
||||
|
||||
??? tip "Подсказки"
|
||||
|
||||
1. Можно создать отображение из закрывающей скобки в соответствующую открывающую
|
||||
2. Встретив закрывающую скобку, сначала проверьте, не пуст ли стек, а затем — совпадает ли его вершина
|
||||
3. После обхода стек также должен быть пуст
|
||||
|
||||
[LeetCode](https://leetcode.com/problems/valid-parentheses/){ .rounded-button .exercise-button target="_blank" rel="noopener noreferrer" }
|
||||
Reference in New Issue
Block a user