|
| 1 | +# Combination Sum |
| 2 | + |
| 3 | +Page on leetcode: https://leetcode.com/problems/combination-sum/ |
| 4 | + |
| 5 | +## Problem Statement |
| 6 | + |
| 7 | +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. |
| 8 | + |
| 9 | +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. |
| 10 | + |
| 11 | +It is guaranteed that the number of unique combinations that sum up to target is less than 150 combinations for the given input. |
| 12 | + |
| 13 | +### Constraints |
| 14 | + |
| 15 | +- 1 <= candidates.length <= 30 |
| 16 | +- 1 <= candidates[i] <= 200 |
| 17 | +- All elements of candidates are distinct. |
| 18 | +- 1 <= target <= 500 |
| 19 | + |
| 20 | +### Example |
| 21 | + |
| 22 | +``` |
| 23 | +Input: candidates = [2,3,6,7], target = 7 |
| 24 | +Output: [[2,2,3],[7]] |
| 25 | +Explanation: |
| 26 | +2 and 3 are candidates, and 2 + 2 + 3 = 7. Note that 2 can be used multiple times. |
| 27 | +7 is a candidate, and 7 = 7. |
| 28 | +These are the only two combinations. |
| 29 | +``` |
| 30 | + |
| 31 | +## Solution |
| 32 | + |
| 33 | +- can I use greedy? |
| 34 | +- array not sorted |
| 35 | +- iterate thru each element |
| 36 | +- need a result array |
| 37 | + |
| 38 | +### Pseudocode |
| 39 | + |
| 40 | +1. Iterate thru array |
| 41 | +2. while sum is less than target keep summing |
| 42 | +3. iterate on second loop |
| 43 | + |
| 44 | +### Initial Attempt |
| 45 | + |
| 46 | +```javascript |
| 47 | +const combinationSum = function (candidates, target) { |
| 48 | + for (let i = 0; i < candidates.length; i++) { |
| 49 | + let sum = 0; |
| 50 | + const possible = []; |
| 51 | + while (sum < target) { |
| 52 | + sum += candidates[i]; |
| 53 | + possible.push(candidate[i]); |
| 54 | + for (let j = i + 1; j < candidates.length; j++) {} |
| 55 | + } |
| 56 | + } |
| 57 | +}; |
| 58 | +``` |
| 59 | + |
| 60 | +### Optimized Solution |
| 61 | + |
| 62 | +The below approach uses DFS recursion and a state space tree. The time complexity is O(2<sup>t</sup>) and space complexity is O(length of longest combo array). A discussion about time and space complexity can be found here: https://leetcode.com/problems/combination-sum/discuss/1755084/Detailed-Time-and-Space-Complecity-analysisc++javabacktracking |
| 63 | + |
| 64 | +You can see an explanation of this solution here: https://www.youtube.com/watch?v=GBKI9VSKdGg |
| 65 | + |
| 66 | +```javascript |
| 67 | +const combinationSum = function (candidates, target) { |
| 68 | + const result = []; |
| 69 | + |
| 70 | + function dfs(i, combo, total) { |
| 71 | + if (total === target) { |
| 72 | + // Found a combo that adds to target, add a copy to the result so that you don't overwrite it on subsequent recursive calls. |
| 73 | + result.push([...combo]); |
| 74 | + return; |
| 75 | + } else if (total > target || i >= candidates.length) { |
| 76 | + // Can't go any further down this path |
| 77 | + return; |
| 78 | + } |
| 79 | + |
| 80 | + // Continue down left path which adds another occurrence of candidates[i] |
| 81 | + combo.push(candidates[i]); |
| 82 | + dfs(i, combo, total + candidates[i]); |
| 83 | + |
| 84 | + // Continue down the right path with no more occurrences of candidates[i] |
| 85 | + combo.pop(); |
| 86 | + dfs(i + 1, combo, total); |
| 87 | + } |
| 88 | + |
| 89 | + dfs(0, [], 0); |
| 90 | + return result; |
| 91 | +}; |
| 92 | +``` |
0 commit comments