TGViewer
Swift | LeetCode Swift | LeetCode @easy_swift_task · 1.3K subscribers
Post #1048 116
Задача: 39. Combination Sum
Сложность: medium

Дан массив уникальных целых чисел candidates и целевое целое число target. Верните список всех уникальных комбинаций из candidates, где выбранные числа в сумме дают target. Комбинации можно возвращать в любом порядке.

Одно и то же число может быть выбрано из массива candidates неограниченное количество раз. Две комбинации считаются уникальными, если частота хотя бы одного из выбранных чисел отличается.

Тестовые случаи сгенерированы таким образом, что количество уникальных комбинаций, дающих в сумме target, меньше 150 комбинаций для данного ввода.

Пример:
Input: candidates = [2,3,5], target = 8
Output: [[2,2,2,2],[2,3,3],[3,5]]


👨‍💻 Алгоритм:

1⃣Как видно, вышеописанный алгоритм обратного отслеживания разворачивается как обход дерева в глубину (DFS - Depth-First Search), который часто реализуется с помощью рекурсии.
Здесь мы определяем рекурсивную функцию backtrack(remain, comb, start) (на Python), которая заполняет комбинации, начиная с текущей комбинации (comb), оставшейся суммы для выполнения (remain) и текущего курсора (start) в списке кандидатов.
Следует отметить, что сигнатура рекурсивной функции немного отличается в Java, но идея остается той же.

2⃣Для первого базового случая рекурсивной функции, если remain == 0, то есть мы достигаем желаемой целевой суммы, поэтому мы можем добавить текущую комбинацию в итоговый список.
Как другой базовый случай, если remain < 0, то есть мы превышаем целевое значение, мы прекращаем исследование на этом этапе.

3⃣Помимо вышеупомянутых двух базовых случаев, мы затем продолжаем исследовать подсписок кандидатов, начиная с [start ... n].
Для каждого из кандидатов мы вызываем рекурсивную функцию саму с обновленными параметрами.
Конкретно, мы добавляем текущего кандидата в комбинацию.
С добавленным кандидатом у нас теперь меньше суммы для выполнения, то есть remain - candidate.
Для следующего исследования мы все еще начинаем с текущего курсора start.
В конце каждого исследования мы делаем откат, удаляя кандидата из комбинации.

😎 Решение:
class Solution {
func backtrack(_ remain: Int, _ comb: inout [Int], _ start: Int, _ candidates: [Int], _ results: inout [[Int]]) {
if remain == 0 {
results.append(comb)
return
} else if remain < 0 {
return
}

for i in start..<candidates.count {
comb.append(candidates[i])
backtrack(remain - candidates[i], &comb, i, candidates, &results)
comb.removeLast()
}
}

func combinationSum(_ candidates: [Int], _ target: Int) -> [[Int]] {
var results = [[Int]]()
var comb = [Int]()

backtrack(target, &comb, 0, candidates, &results)
return results
}
}


Ставь 👍 и забирай 📚 Базу знаний
More from @easy_swift_task
  1. Oct 13, 2026Задача: 786. K-th Smallest Prime Fraction Сложность: medium Вам дан отсортированный массив…
  2. Oct 11, 2026Задача: 1325. Delete Leaves With a Given Value Сложность: medium Дано корневое дерево root…
  3. Oct 7, 2026🔥 Скрытые вакансии с удаленной работой для iOS разработчика, которые нигде больше не публ…
  4. Oct 4, 2026Задача: 523. Continuous Subarray Sum Сложность: medium Дан целочисленный массив nums и цел…
  5. Oct 4, 2026Задача: 1329. Sort the Matrix Diagonally Сложность: medium Диагональ матрицы — это диагона…
  6. Oct 3, 2026Задача: 200. Number of Islands Сложность: medium Дана двумерная бинарная сетка размером m…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →