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 = 7 Output: [[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 = 8 Output: [[2,2,2,2],[2,3,3],[3,5]]
Example 3:
Input: candidates = [2], target = 1 Output: []
Example 4:
Input: candidates = [1], target = 1 Output: [[1]]
Example 5:
Input: candidates = [1], target = 2 Output: [[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 backtracking approach 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!