mirror of
https://github.com/krahets/hello-algo.git
synced 2026-07-23 03:46:05 +00:00
build
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
---
|
||||
comments: true
|
||||
---
|
||||
|
||||
<!-- Автоматически создано utils/exercises/publish_exercises.py; не редактируйте напрямую. -->
|
||||
|
||||
# 4.6 Упражнения
|
||||
|
||||
## 4.6.1 Вопросы для самопроверки
|
||||
|
||||
### 1. Как массив и связный список находят элемент
|
||||
|
||||
В массиве и односвязном списке по порядку хранятся `[A, B, C, D, E]`. Требуется прочитать 4-й элемент `D`.
|
||||
|
||||
<!-- numbered-subquestions -->
|
||||
|
||||
1. Какой индекс можно напрямую использовать в массиве?
|
||||
2. Через какие узлы нужно последовательно пройти по `next` в односвязном списке, начиная с головного узла `A`?
|
||||
3. Как меняется число шагов в каждой структуре по мере удаления нужного элемента от начала? Какая структура лучше подходит для многократного доступа по позиции и почему?
|
||||
|
||||
??? success "Ответ"
|
||||
|
||||
1. Если индексация начинается с 0, индекс 4-го элемента равен 3, поэтому в массиве можно напрямую обратиться к `arr[3]`.
|
||||
|
||||
2. В односвязном списке нужно начинать с головы. Путь имеет вид `A → B → C → D`, то есть по `next` нужно перейти 3 раза.
|
||||
|
||||
3. Массив позволяет напрямую определить положение элемента по адресу начала и индексу, поэтому временная сложность доступа по позиции равна $O(1)$.
|
||||
Чтобы обратиться к $k$-му узлу односвязного списка, нужно начать с головного узла и перейти по `next` $k-1$ раз,
|
||||
что в худшем случае требует $O(n)$ времени.
|
||||
|
||||
Здесь сравнивается только доступ по позиции; это не означает, что связный список медленнее при всех операциях.
|
||||
|
||||
### 2. Как вставить элемент в массив и связный список
|
||||
|
||||
В массиве и односвязном списке хранятся `A, B, C, D`. Требуется вставить `X` после `B`.
|
||||
|
||||
- емкость массива равна 5, его текущее состояние — `[A, B, C, D, _]`;
|
||||
- связный список имеет вид `A → B → C → D`, и ссылка на узел `B` уже получена.
|
||||
|
||||
<!-- numbered-subquestions -->
|
||||
|
||||
1. Какие элементы массива нужно переместить? Запишите массив после вставки.
|
||||
2. В каком порядке следует изменить `X.next` и `B.next`? Запишите связный список после вставки.
|
||||
3. Почему при сравнении эффективности вставки важно уточнить, что «ссылка на узел B уже получена»?
|
||||
|
||||
??? success "Ответ"
|
||||
|
||||
1. В массиве сначала нужно сдвинуть `D` на одну позицию вправо, затем так же сдвинуть `C` и, наконец, поместить `X` по индексу 2.
|
||||
Получится `[A, B, X, C, D]`.
|
||||
|
||||
2. Изначально `B.next` указывает на `C`. Сначала следует выполнить `X.next = B.next`, чтобы `X` указывал на `C`,
|
||||
а затем `B.next = X`. Получится `A → B → X → C → D`.
|
||||
Если сначала перезаписать `B.next`, не сохранив прежнюю связь, узел `C` можно потерять.
|
||||
|
||||
3. Если положение `B` известно, для вставки в связный список достаточно изменить две связи, что занимает $O(1)$ времени.
|
||||
Если же `B` еще нужно искать от головы списка, сам поиск может потребовать $O(n)$ времени.
|
||||
|
||||
### 3. Как растет емкость списка
|
||||
|
||||
Список на основе массива сейчас содержит `[A, B, C]`, его длина `size = 3`, а емкость `capacity = 4`.
|
||||
При нехватке места емкость нового массива увеличивается в 2 раза.
|
||||
|
||||
<!-- numbered-subquestions -->
|
||||
|
||||
1. Чему будут равны длина и емкость списка после добавления `D`? Потребуется ли увеличить емкость?
|
||||
2. Затем добавляют `E`. Какой станет емкость и сколько прежних элементов потребуется скопировать?
|
||||
3. Длина базового массива неизменна. Почему тогда кажется, что емкость списка может расти?
|
||||
|
||||
??? success "Ответ"
|
||||
|
||||
1. `D` можно поместить в последнюю свободную ячейку. Теперь содержимое равно `[A, B, C, D]`,
|
||||
`size = 4`, `capacity = 4`, и увеличивать емкость не требуется.
|
||||
|
||||
2. Для `E` свободного места уже нет, поэтому нужно создать новый массив емкостью 8,
|
||||
скопировать в него 4 прежних элемента `A, B, C, D`, а затем добавить `E`.
|
||||
После этого `size = 5`, `capacity = 8`.
|
||||
|
||||
3. Исходный массив сам по себе не удлиняется. Список создает новый массив большего размера, копирует прежние элементы
|
||||
и затем использует новый массив как базовое хранилище. Поэтому для пользователя емкость выглядит увеличившейся.
|
||||
|
||||
## 4.6.2 Задачи по программированию
|
||||
|
||||
### 1. Прибавление единицы к большому числу в массиве
|
||||
|
||||
Массив `digits` хранит слева направо цифры неотрицательного целого числа. Например, `[3, 0, 8]` обозначает 308.
|
||||
Число 0 представлено как `[0]`; у всех остальных входных данных первая цифра не равна 0.
|
||||
|
||||
Смоделируйте сложение столбиком в десятичной системе: увеличьте это число на 1 и верните результат в том же формате массива.
|
||||
Массив `digits` можно изменять непосредственно. Если перед первой цифрой появляется новый перенос, можно вернуть более длинный массив.
|
||||
|
||||
??? tip "Подсказки"
|
||||
|
||||
1. Как при сложении столбиком, начните с последней цифры массива
|
||||
2. Если текущая цифра меньше 9, увеличьте ее на один и сразу верните результат
|
||||
3. Если текущая цифра равна 9, замените ее на 0; если все цифры равны 9, добавьте 1 в начало
|
||||
|
||||
[LeetCode](https://leetcode.com/problems/plus-one/){ .rounded-button .exercise-button target="_blank" rel="noopener noreferrer" }
|
||||
|
||||
### 2. Разворот односвязного списка
|
||||
|
||||
Дан головной узел `head` односвязного списка. Каждый узел содержит значение и поле `next`, указывающее на следующий узел.
|
||||
|
||||
Итеративно разверните все связи между узлами и верните новый головной узел.
|
||||
Не создавайте новые узлы связного списка.
|
||||
|
||||
??? tip "Подсказки"
|
||||
|
||||
1. Нарисуйте на бумаге три связанных узла и два указателя prev и cur
|
||||
2. Прежде чем изменить cur.next, сохраните исходный следующий узел в nxt
|
||||
3. Развернув cur.next, выполните prev = cur, затем cur = nxt и продолжайте с очередным узлом исходного списка
|
||||
|
||||
[LeetCode](https://leetcode.com/problems/reverse-linked-list/){ .rounded-button .exercise-button target="_blank" rel="noopener noreferrer" }
|
||||
@@ -20,3 +20,4 @@ icon: material/view-list-outline
|
||||
- [4.3 Список](list.md)
|
||||
- [4.4 Оперативная память и кэш *](ram_and_cache.md)
|
||||
- [4.5 Резюме](summary.md)
|
||||
- [4.6 Упражнения](exercises.md)
|
||||
|
||||
Reference in New Issue
Block a user