1+ import java .util .*;
2+ class Solution {
3+ public List <List <Integer >> combinationSum (int [] candidates , int target ) {
4+ List <List <Integer >> result = new ArrayList <>();
5+ List <Integer > temp = new ArrayList <>();
6+
7+ backtrack (candidates , target , 0 , temp , result );
8+ return result ;
9+ }
10+ private void backtrack (int [] candidates , int target , int start , List <Integer > temp , List <List <Integer >> result ) {
11+ if (target < 0 ) return ;
12+ if (target == 0 ) {
13+ result .add (new ArrayList <>(temp )); // deep copy
14+ return ;
15+ }
16+
17+ for (int i = start ; i < candidates .length ; i ++) {
18+ temp .add (candidates [i ]);
19+ backtrack (candidates , target - candidates [i ], i , temp , result );
20+ temp .remove (temp .size () -1 );
21+ }
22+
23+ }
24+ }
25+
26+ /**
27+ Return all unique combinations where the candidate num sum to target
28+ - each num in cand[] can be used unlimited times
29+ - order of num in comb does NOT matter
30+
31+ 1. use backtracking to explore all possible comb
32+ 2. backtrack, if current sum > target
33+ 3. save comb, if current sum == target
34+ 4. avoid dupl -> only consider num from crnt idx onward (no going back)
35+
36+ Time: O(2^target)
37+ Space: O(target)
38+
39+ Learned: Backtracking vs DFS
40+ - DFS: search all paths deeply (no conditions, no rollback).
41+ - Backtracking = DFS + decision making + undo step.
42+ Explore, prune (if invalid), save (if valid), then undo last choice.
43+
44+ for (์ ํ ๊ฐ๋ฅํ ์ซ์ ํ๋์ฉ) {
45+ ์ ํํ๊ณ
46+ target ์ค์ด๊ณ (๋ชฉํ ๊ฐ๊น์์ง)
47+ ์ฌ๊ท ํธ์ถ๋ก ๋ค์ ์ ํ
48+ ์คํจํ๊ฑฐ๋ ์ฑ๊ณตํ๋ฉด ๋๋๋ฆฌ๊ธฐ (๋ฐฑํธ๋ํน)
49+ }
50+
51+ DFS just visits everything,
52+ Backtracking visits only whatโs promising โ and turns back if not!
53+ */
0 commit comments