Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update combination_sum.py #12431

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 64 additions & 33 deletions backtracking/combination_sum.py
Original file line number Diff line number Diff line change
@@ -1,66 +1,97 @@
"""
In the Combination Sum problem, we are given a list consisting of distinct integers.
We need to find all the combinations whose sum equals to target given.
We can use an element more than one.
"""

Check failure on line 1 in backtracking/combination_sum.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff

backtracking/combination_sum.py:1:1: SyntaxError: Unexpected indentation
Combination Sum Problem

Time complexity(Average Case): O(n!)
Description:
Given a list of distinct integers (candidates), find all unique combinations where the sum of elements equals the given target.

Check failure on line 5 in backtracking/combination_sum.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E501)

backtracking/combination_sum.py:5:89: E501 Line too long (127 > 88)
An element can be used multiple times in a combination.

Constraints:
1 <= candidates.length <= 30
2 <= candidates[i] <= 40
All elements of candidates are distinct.
1 <= target <= 40
"""

Time complexity (Average Case): O(n!)
"""

def backtrack(

Check failure on line 17 in backtracking/combination_sum.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff

backtracking/combination_sum.py:17:1: SyntaxError: Expected a statement
candidates: list, path: list, answer: list, target: int, previous_index: int
candidates: list[int],
path: list[int],
answer: list[list[int]],
target: int,
start_index: int
) -> None:
"""
A recursive function that searches for possible combinations. Backtracks in case
of a bigger current combination value than the target value.
Recursive helper function to find all valid combinations.

Parameters
Parameters:
----------
previous_index: Last index from the previous search
target: The value we need to obtain by summing our integers in the path list.
answer: A list of possible combinations
path: Current combination
candidates: A list of integers we can use.
candidates : list[int]
A list of distinct integers we can use to form combinations.
path : list[int]
The current combination being formed.
answer : list[list[int]]
The list of valid combinations that sum to the target.
target : int
The remaining sum needed to reach the target.
start_index : int
The index to start searching from in the candidates list.

Returns:
-------
None
"""
if target == 0:
answer.append(path.copy())
else:
for index in range(previous_index, len(candidates)):
if target >= candidates[index]:
path.append(candidates[index])
backtrack(candidates, path, answer, target - candidates[index], index)
path.pop(len(path) - 1)
return

for i in range(start_index, len(candidates)):
if candidates[i] <= target:
path.append(candidates[i])
backtrack(candidates, path, answer, target - candidates[i], i) # Same index for reuse

Check failure on line 51 in backtracking/combination_sum.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E501)

backtracking/combination_sum.py:51:89: E501 Line too long (98 > 88)
path.pop() # Backtrack

def combination_sum(candidates: list, target: int) -> list:
def combination_sum(candidates: list[int], target: int) -> list[list[int]]:
"""
Finds all unique combinations of candidates that sum up to the target.

Parameters:
----------
candidates : list[int]
A list of distinct integers.
target : int
The target sum we want to achieve.

Returns:
-------
list[list[int]]
A list of all unique combinations.

Examples:
--------
>>> combination_sum([2, 3, 5], 8)
[[2, 2, 2, 2], [2, 3, 3], [3, 5]]
>>> combination_sum([2, 3, 6, 7], 7)
[[2, 2, 3], [7]]
>>> combination_sum([-8, 2.3, 0], 1)
Traceback (most recent call last):
...
RecursionError: maximum recursion depth exceeded
>>> combination_sum([], 7)
[]
>>> combination_sum([1], 0)
[]
"""
path = [] # type: list[int]
answer = [] # type: list[int]
backtrack(candidates, path, answer, target, 0)
return answer
if not candidates or target <= 0:
return []

answer: list[list[int]] = []
backtrack(candidates, [], answer, target, 0)
return answer

def main() -> None:
print(combination_sum([-8, 2.3, 0], 1))

"""Main function to test the combination_sum function."""
print("Example 1:", combination_sum([2, 3, 5], 8))
print("Example 2:", combination_sum([2, 3, 6, 7], 7))
print("Example 3 (Invalid input):", combination_sum([], 1)) # Should return []

if __name__ == "__main__":
import doctest

doctest.testmod()
main()
Loading