mirror of
https://github.com/krahets/hello-algo.git
synced 2026-07-13 07:46:06 +00:00
Update ru translation
This commit is contained in:
@@ -1,35 +1,95 @@
|
||||
我仔细查看了提供的俄文内容,但发现这是关于"回溯算法"(Поиск с возвратом)的通用章节内容,而不是对应中文"子集和问题"(subset_sum_problem)小节的内容。
|
||||
|
||||
俄文内容主要讲述:
|
||||
- 回溯算法的基本概念
|
||||
- 深度优先搜索
|
||||
- 尝试与回退
|
||||
- 剪枝操作
|
||||
- 代码框架
|
||||
|
||||
而中文内容是关于:
|
||||
- 子集和问题的具体实现
|
||||
- 无重复元素的情况
|
||||
- 考虑重复元素的情况
|
||||
- 重复子集剪枝
|
||||
|
||||
**结论:提供的俄文章节内容与中文小节内容不匹配。**
|
||||
|
||||
要完成对齐任务,我需要:
|
||||
1. 俄文版本中对应"子集和问题"(subset_sum_problem)的具体内容
|
||||
2. 或者确认俄文版本中是否存在这个小节
|
||||
|
||||
**建议:**
|
||||
- 请提供俄文版本中关于"子集和问题"或"Задача о сумме подмножеств"的章节内容
|
||||
- 或者提供完整的俄文 chapter_backtracking 目录结构,以便定位正确的对应内容
|
||||
|
||||
如果俄文版本确实缺少这个小节,我可以生成如下标记:
|
||||
|
||||
```markdown
|
||||
# Задача о сумме подмножеств
|
||||
|
||||
<!-- 🔴 俄文版完全缺失此小节 -->
|
||||
<!-- 中文原文:子集和问题 - 包含无重复元素和考虑重复元素两种情况的完整实现 -->
|
||||
## Случай без повторяющихся элементов
|
||||
|
||||
!!! question
|
||||
|
||||
Дан массив положительных целых чисел `nums` и целевое положительное целое число `target`. Найдите все возможные комбинации, сумма элементов которых равна `target`. В заданном массиве нет повторяющихся элементов, каждый элемент может быть выбран несколько раз. Верните эти комбинации в виде списка, в котором не должно быть повторяющихся комбинаций.
|
||||
|
||||
Например, для входного множества $\{3, 4, 5\}$ и целевого числа $9$ решениями будут $\{3, 3, 3\}, \{4, 5\}$. Следует обратить внимание на следующие два момента:
|
||||
|
||||
- элементы входного множества можно выбирать неограниченное количество раз;
|
||||
- порядок элементов в подмножестве не имеет значения, например $\{4, 5\}$ и $\{5, 4\}$ — одно и то же подмножество.
|
||||
|
||||
### Сравнение с решением задачи о полных перестановках
|
||||
|
||||
Подобно задаче о полных перестановках, процесс генерации подмножеств можно представить как серию выборов, а в процессе выбора в реальном времени обновлять сумму элементов. Когда сумма элементов равна `target`, подмножество записывается в список результатов.
|
||||
|
||||
Однако, в отличие от задачи о полных перестановках, **в данной задаче элементы множества можно выбирать неограниченное количество раз**, поэтому нет необходимости использовать булев список `selected` для записи выбранных элементов. Для получения начального решения можно просто немного изменить код для полных перестановок.
|
||||
|
||||
```src
|
||||
[file]{subset_sum_i_naive}-[class]{}-[func]{subset_sum_i_naive}
|
||||
```
|
||||
|
||||
请确认是否需要这样处理,或者提供正确的俄文对应内容。
|
||||
При вводе в этот код массива $[3, 4, 5]$ и целевого элемента $9$ будет выведено $[3, 3, 3], [4, 5], [5, 4]$. **Хотя удалось найти все подмножества с суммой $9$, среди них есть повторяющиеся подмножества $[4, 5]$ и $[5, 4]$**.
|
||||
|
||||
Это происходит потому, что процесс поиска различает порядок выбора, тогда как в подмножествах порядок элементов не важен. Как показано на рисунке ниже, сначала выбрать $4$, а затем $5$ и сначала выбрать $5$, а затем $4$ — это разные ветви, но они соответствуют одному и тому же подмножеству.
|
||||
|
||||

|
||||
|
||||
**Одним из очевидных подходов к устранению повторяющихся подмножеств является удаление дубликатов из списка результатов**. Однако этот метод очень неэффективен по двум причинам:
|
||||
|
||||
- Когда в массиве много элементов, особенно когда значение `target` велико, процесс поиска генерирует множество повторяющихся подмножеств.
|
||||
- Сравнение подмножеств (массивов) на различия — очень затратная по времени операция. Она требует сначала сортировки массивов, затем сравнения различий каждого элемента в массиве.
|
||||
|
||||
### Обрезка повторяющихся подмножеств
|
||||
|
||||
**Рассмотрим устранение дубликатов в процессе поиска с помощью обрезки**. На рисунке ниже показано, что повторяющиеся подмножества возникают при выборе элементов массива в разном порядке, например в следующих случаях:
|
||||
|
||||
1. Пусть на первом и втором этапах выбираются $3$ и $4$ соответственно, создаются все подмножества, содержащие эти два элемента, обозначенные как $[3, 4, \dots]$.
|
||||
2. Затем если на первом этапе выбирается $4$, **то на втором этапе следует пропустить $3$**, так как подмножество $[4, 3, \dots]$ полностью повторяет подмножество, созданное на этапе `1.`.
|
||||
|
||||
В процессе поиска выбор на каждом уровне осуществляется слева направо. Поэтому чем правее ветвь, тем больше она обрезается.
|
||||
|
||||
1. На первых двух этапах выбираются $3$ и $5$ и создаются подмножества $[3, 5, \dots]$.
|
||||
2. На первых двух этапах выбираются $4$ и $5$ и создаются подмножества $[4, 5, \dots]$.
|
||||
3. Если на первом этапе выбирается $5$, **то на втором этапе следует пропустить $3$ и $4$**, так как подмножества $[5, 3, \dots]$ и $[5, 4, \dots]$ полностью повторяют подмножества, описанные на этапах `1.` и `2.`.
|
||||
|
||||

|
||||
|
||||
Обобщим эту мысль. Пусть задан входной массив $[x_1, x_2, \dots, x_n]$. Тогда в процессе поиска последовательность выбора $[x_{i_1}, x_{i_2}, \dots, x_{i_m}]$ должна удовлетворять условию $i_1 \leq i_2 \leq \dots \leq i_m$, **в противном случае она приведет к дубликатам, и ее нужно обрезать**.
|
||||
|
||||
### Код реализации
|
||||
|
||||
Для реализации этой обрезки мы инициализируем переменную `start`, которая указывает начальную точку обхода. **После выбора $x_{i}$ следующая итерация начинается с индекса $i$**. Это позволяет для последовательности выбора соблюдать условие $i_1 \leq i_2 \leq \dots \leq i_m$, обеспечивая уникальность подмножеств.
|
||||
|
||||
Кроме того, в код были внесены следующие две оптимизации:
|
||||
|
||||
- Перед началом поиска массив `nums` сортируется. При обходе всех вариантов, **если сумма подмножества превышает `target`, цикл завершается**, так как последующие элементы больше, и их сумма также превысит `target`.
|
||||
- Исключение переменной `total`, **подсчет суммы элементов осуществляется с помощью вычитания из `target`**. Решение фиксируется, когда `target` равен $0$.
|
||||
|
||||
```src
|
||||
[file]{subset_sum_i}-[class]{}-[func]{subset_sum_i}
|
||||
```
|
||||
|
||||
На рисунке ниже показан полный процесс поиска с возвратом для массива $[3, 4, 5]$ и целевого элемента $9$.
|
||||
|
||||

|
||||
|
||||
## Случай с повторяющимися элементами
|
||||
|
||||
!!! question
|
||||
|
||||
Дан массив положительных целых чисел `nums` и целевое положительное целое число `target`. Найдите все возможные комбинации, сумма элементов которых равна `target`. **Заданный массив может содержать повторяющиеся элементы, каждый элемент может быть выбран только один раз**. Верните эти комбинации в виде списка, в котором не должно быть повторяющихся комбинаций.
|
||||
|
||||
В отличие от предыдущей задачи **входной массив может содержать повторяющиеся элементы**, что создает новую проблему. Например, для массива $[4, \hat{4}, 5]$ и целевого элемента $9$ текущий код выдает результат $[4, 5], [\hat{4}, 5]$, что приводит к повторяющимся подмножествам.
|
||||
|
||||
**Причина этих повторов в том, что равные элементы выбираются несколько раз на одном этапе**. На рисунке ниже показано, что на первом этапе есть три варианта выбора, два из которых равны $4$. Это приводит к двум повторяющимся ветвям поиска и, следовательно, к повторяющимся подмножествам. Аналогично два элемента $4$ на втором этапе также создают повторяющиеся подмножества.
|
||||
|
||||

|
||||
|
||||
### Обрезка равных элементов
|
||||
|
||||
Для решения этой проблемы **необходимо сделать выбор равных элементов на каждом этапе однократным**. Реализация этого подхода довольно изящна: поскольку массив отсортирован, равные элементы находятся рядом друг с другом. Это означает, что если текущий элемент равен предыдущему, то он уже был выбран, и его следует пропустить.
|
||||
|
||||
В то же время **в этой задаче предусмотрено, что каждый элемент массива может быть выбран только один раз**. К счастью, можно использовать переменную `start` для выполнения этого ограничения: после выбора $x_{i}$ начинаем следующий цикл с индекса $i + 1$. Это позволяет исключить повторяющиеся подмножества и избежать повторного выбора элементов.
|
||||
|
||||
### Код реализации
|
||||
|
||||
```src
|
||||
[file]{subset_sum_ii}-[class]{}-[func]{subset_sum_ii}
|
||||
```
|
||||
|
||||
На рисунке ниже демонстрируется процесс обратного отслеживания для массива $[4, 4, 5]$ и целевого элемента $9$, включающий четыре вида обрезки. Проанализируйте рисунок и комментарии в коде, чтобы лучше понять весь процесс поиска и как работают различные операции обрезки.
|
||||
|
||||

|
||||
|
||||
Reference in New Issue
Block a user