Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
The same repeated number may be chosen from C unlimited number of times.
Note:
All numbers (including target) will be positive integers.
Elements in a combination (a1, a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
The combinations themselves must be sorted in ascending order.
CombinationA > CombinationB iff (a1 > b1) OR (a1 = b1 AND a2 > b2) OR … (a1 = b1 AND a2 = b2 AND … ai = bi AND ai+1 > bi+1)
The solution set must not contain duplicate combinations.
Example, Given candidate set 2,3,6,7 and target 7, A solution set is:
[2, 2, 3]
[7]
Method:
Sort original list first, recursively add number into a candidate list, check if sum equals target. We only add number greater than or equal to current number's index to remove duplicates.
Solution:
Time: O(n^k) , k = target/min number Space: O(n^k)
public class Solution { public ArrayList<ArrayList<Integer>> combinationSum(ArrayList<Integer> A, int B) { ArrayList<ArrayList<Integer>> result = new ArrayList<>(); ArrayList<Integer> current = new ArrayList<>(); Collections.sort(A); helper(result, current, A, B, 0, 0); return result; }
private void helper(ArrayList<ArrayList<Integer>> result, ArrayList<Integer> current, ArrayList<Integer> A, int B, int sum, int index) { if (sum > B) { return; } if (sum == B) { ArrayList<Integer> solution = new ArrayList<>(current); result.add(solution); return; } for (int i = index; i < A.size(); i++) { int val = A.get(i); if (i < A.size() - 1 && val == A.get(i + 1)) { continue; } current.add(val); sum += val; helper(result, current, A, B, sum, i); sum -= val; current.remove(current.size() - 1); } } }