## Description

https://leetcode.com/problems/combination-sum/

Given an array of **distinct** integers `candidates`

and a target integer `target`

, return *a list of all unique combinations of *

`candidates`

*where the chosen numbers sum to*

`target`

*.*You may return the combinations in

**any order**.

The **same** number may be chosen from `candidates`

an **unlimited number of times**. Two combinations are unique if the frequency of at least one of the chosen numbers is different.

It is **guaranteed** that the number of unique combinations that sum up to `target`

is less than `150`

combinations for the given input.

**Example 1:**

Input:candidates = [2,3,6,7], target = 7Output:[[2,2,3],[7]]Explanation:2 and 3 are candidates, and 2 + 2 + 3 = 7. Note that 2 can be used multiple times. 7 is a candidate, and 7 = 7. These are the only two combinations.

**Example 2:**

Input:candidates = [2,3,5], target = 8Output:[[2,2,2,2],[2,3,3],[3,5]]

**Example 3:**

Input:candidates = [2], target = 1Output:[]

**Example 4:**

Input:candidates = [1], target = 1Output:[[1]]

**Example 5:**

Input:candidates = [1], target = 2Output:[[1,1]]

**Constraints:**

`1 <= candidates.length <= 30`

`1 <= candidates[i] <= 200`

- All elements of
`candidates`

are**distinct**. `1 <= target <= 500`

## Explanation

Combinations are similar to subsets of the candidate array. We can use depth-first search to find all combinations of the input array.

First, sort candidates array into ascending order.

Second, conduct a backtracking to visit each combination of the input array.

A backtracking function would be:

Whenever adding an element to the combination, we reduce the target.

If the remaining target value is equal to 0, we add the current combination to the result list.

Then, recursively find all combinations for the remaining target value from the remaining elements.

## Java Solution

```
class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> results = new ArrayList<>();
if (candidates == null || candidates.length == 0) {
return results;
}
Arrays.sort(candidates);
List<Integer> combination = new ArrayList<>();
toFindCombinationsToTarget(results, combination, candidates, target, 0);
return results;
}
private void toFindCombinationsToTarget(List<List<Integer>> results, List<Integer> combination, int[] candidates, int target, int startIndex) {
if (target == 0) {
results.add(new ArrayList<>(combination));
return;
}
for (int i = startIndex; i < candidates.length; i++) {
if (candidates[i] > target) {
break;
}
combination.add(candidates[i]);
toFindCombinationsToTarget(results, combination, candidates, target - candidates[i], i);
combination.remove(combination.size() - 1);
}
}
}
```

## Python Solution

```
class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
results = []
if not candidates:
return results
candidates = sorted(candidates)
combination = []
self.helper(results, candidates, combination, target, 0)
return results
def helper(self, results, candidates, combination, target, start_index):
if target == 0:
results.append(list(combination))
return
for i in range(start_index, len(candidates)):
if candidates[i] > target:
break
combination.append(candidates[i])
self.helper(results, candidates, combination, target - candidates[i], i)
combination.pop()
```

- Time Complexity: ~(N^(T/M + 1))
- Space Complexity: ~T/M

N is the number of candidates, T is the target value, and M is the minimal value among the candidates

We donot actually need to sort the candidates here :).

Hey GoodTecher! Thank you so much for the tutorials! They are awesome. Can you please do more DP problems, showing how to think and attack those problems?

Also, please do Combination Sum IV.

Thank you Yamato. Will take a look at the question ðŸ™‚

Hi Good Techer,

Thank you so much for making this video in comparison with the previous one. They are very helpful.

Looking forward to your next video.

With all my thanks,

Sure! You are welcome!