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