# 39. Combination Sum
#### Difficulty: Medium
link: https://leetcode.com/problems/combination-sum/
### 1. Backtracking
#### $O(n^m)$ runtime, $O(n^m)$ space
###### n = len(candidates), m = target / min(candidates)
### 走法1
result紀錄最終的答案,path紀錄走過的路徑,start_index代表從candidates的哪個index開始往後檢查,value則是還差多少值就達到target。
每次backtracking會判斷下一個要拿哪個candidate,由於candidates已經先將數字從小到大排序好,如果超過需要達成的value還能early stop。
##### python
```python=
class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
candidates.sort()
result = []
def backtracking(path, start_index, value):
for i in range(start_index, len(candidates)):
cand = candidates[i]
if cand < value:
backtracking(path + [cand], i, value - cand)
elif cand == value:
result.append(path + [cand])
else:
break
backtracking([], 0, target)
return result
```
### 走法2
backtrack每次選擇要或不要拿now_idx這個的元素,如果不拿就往下一個元素看,如果拿就繼續待在同一個元素。
##### python
```python=
class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
ans = []
def backtrack(now_ans, now_idx, now_target):
if now_target == 0:
ans.append(now_ans)
return
if now_idx == len(candidates) or now_target < 0:
return
backtrack(now_ans+[candidates[now_idx]], now_idx, now_target-candidates[now_idx])
backtrack(now_ans, now_idx+1, now_target)
backtrack([], 0, target)
return ans
```
###### tags: `leetcode`