Skip to content

Commit 8f1d2c8

Browse files
committed
Feature: Added a new backtracking question for the better understanding of combination sum
1 parent e2a78d4 commit 8f1d2c8

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

backtracking/combination_sum_2.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
"""
2+
In this Combination Problem, we are given a list consisting of distinct integers.
3+
We need to find all the combinations whose sum equals to target given.
4+
We cannot use an element more than one.
5+
6+
Time complexity(Average Case): O(n * 2^(n/2))
7+
8+
9+
Constraints:
10+
1 <= candidates.length <= 100
11+
1 <= candidates[i] <= 50
12+
1 <= target <= 30
13+
"""
14+
15+
def backtrack(candidates: list, target: int, start_index: int, total: int, path: list, answer: list) -> None:
16+
"""
17+
A recursive function that searches for possible combinations. Backtracks in case
18+
of a bigger current combination value than the target value and removes the already
19+
appended values for removing repetition of elements in the solutions.
20+
21+
Parameters
22+
----------
23+
start_index: Last index from the previous search
24+
target: The value we need to obtain by summing our integers in the path list.
25+
answer: A list of possible combinations
26+
path: Current combination
27+
candidates: A list of integers we can use.
28+
total: Sum of elements in path
29+
"""
30+
if target == 0:
31+
answer.append(path.copy())
32+
return
33+
if total == target:
34+
answer.append(path.copy())
35+
return
36+
for i in range(start_index, len(candidates)):
37+
if i > start_index and candidates[i] == candidates[i - 1]:
38+
continue
39+
if total + candidates[i] > target:
40+
break
41+
backtrack(candidates, target, i + 1, total + candidates[i], path + [candidates[i]], answer)
42+
43+
44+
45+
46+
def combination_sum_2(candidates: list,target: int) -> list:
47+
"""
48+
>>> combination_sum_2([10,1,2,7,6,1,5], 8)
49+
[[1, 1, 6], [1, 2, 5], [1, 7], [2, 6]]
50+
>>> combination_sum_2([1,2], 2)
51+
[[2]]
52+
>>> combination_sum_2([-8, 2.3, 0], 1)
53+
Traceback (most recent call last):
54+
...
55+
ValueError: All elements in candidates must be non-negative
56+
>>> combination_sum_2([], 1)
57+
Traceback (most recent call last):
58+
...
59+
ValueError: Candidates list should not be empty
60+
"""
61+
if not candidates:
62+
raise ValueError("Candidates list should not be empty")
63+
64+
if any(x < 0 for x in candidates):
65+
raise ValueError("All elements in candidates must be non-negative")
66+
candidates.sort()
67+
path = []
68+
answer = []
69+
backtrack(candidates, target, 0, 0, path, answer)
70+
return answer
71+
72+
73+
def main() -> None:
74+
print(combination_sum_2([-8, 2.3, 0], 1))
75+
76+
77+
if __name__ == "__main__":
78+
import doctest
79+
80+
doctest.testmod()
81+
main()

0 commit comments

Comments
 (0)