|
| 1 | +// Approach 2: Dynamic Programming |
| 2 | +// ✅ Time Complexity: O(N * T * K) |
| 3 | +// ✅ Space Complexity: O(T * K) |
| 4 | +// N = Number of candidates, T = target, K = average number of combination for each dp[i] |
| 5 | + |
| 6 | +function combinationSum(candidates: number[], target: number): number[][] { |
| 7 | + // candidates = [2, 3] |
| 8 | + // target = 5 |
| 9 | + // dp = [ |
| 10 | + // [[]], // dp[0] |
| 11 | + // [], // dp[1] |
| 12 | + // [[2]], // dp[2] |
| 13 | + // [], // dp[3] |
| 14 | + // [[2, 2]], // dp[4] |
| 15 | + // [] // dp[5] |
| 16 | + // ]; |
| 17 | + |
| 18 | + // dp = [ |
| 19 | + // [[]], // dp[0] |
| 20 | + // [], // dp[1] |
| 21 | + // [[2]], // dp[2] |
| 22 | + // [[3]], // dp[3] |
| 23 | + // [[2, 2]], // dp[4] |
| 24 | + // [[2, 3]] // dp[5] |
| 25 | + // ]; |
| 26 | + |
| 27 | + const dp: number[][][] = Array.from({ length: target + 1 }, () => []); |
| 28 | + // each element in dp is an independent array, and modifying one will not affect others. |
| 29 | + dp[0] = [[]]; |
| 30 | + |
| 31 | + for (const candidate of candidates) { |
| 32 | + for (let num = candidate; num <= target; num++) { |
| 33 | + for (const combination of dp[num - candidate]) { |
| 34 | + dp[num].push([...combination, candidate]); |
| 35 | + } |
| 36 | + } |
| 37 | + } |
| 38 | + |
| 39 | + return dp[target]; |
| 40 | +} |
| 41 | + |
| 42 | +// Approach 1: DFS + Backtracking (Recursive) |
| 43 | +// ✅ Time Complexity: O(N^(T / min)) |
| 44 | +// ✅ Space Complexity: O(K + target / min) |
| 45 | +// If target = 7 and smallest number is 2, recursion can go up to 7 / 2 = levels deep |
| 46 | +// N = number of candidates, T = target value, K = total number of valid combination found |
| 47 | + |
| 48 | +// function combinationSum(candidates: number[], target: number): number[][] { |
| 49 | +// // input: |
| 50 | +// // 1) an array of distinct integers |
| 51 | +// // 2) a target integer |
| 52 | + |
| 53 | +// // output: |
| 54 | +// // a list of all unique combinations of candinates where the chosen numbers sum to target(in any order) |
| 55 | +// // duplicated numbers allowed |
| 56 | + |
| 57 | +// let result: number[][] = []; |
| 58 | +// let nums: number[] = []; |
| 59 | + |
| 60 | +// const dfs = (start: number, total: number) => { |
| 61 | +// if (total > target) { |
| 62 | +// return; |
| 63 | +// } |
| 64 | + |
| 65 | +// if (total === target) { |
| 66 | +// result.push([...nums]); |
| 67 | +// return; |
| 68 | +// } |
| 69 | + |
| 70 | +// for (let i = start; i < candidates.length; i++) { |
| 71 | +// if (total + nums[i] <= target) { |
| 72 | +// nums.push(candidates[i]); |
| 73 | +// dfs(i, total + candidates[i]); |
| 74 | +// nums.pop(); // backtrack |
| 75 | +// } |
| 76 | +// } |
| 77 | +// }; |
| 78 | + |
| 79 | +// dfs(0, 0); |
| 80 | + |
| 81 | +// return result; |
| 82 | +// } |
0 commit comments