3.1 Coins combination
e.g. target = 99 [25, 10, 5, 1]
one possible way 25x3 10x2 5x0 1x4
Assumption:
no duplicate in coin values, array in descending order, not null, not empty, all positive
target >= 0
Input: int[] coin values, int target value
Output: List<List<Integer>> possible combination of coins, the index indicate corresponding coin value in the array
Solution:
# of denomination of levels in the tree, each level consider how many possible cases for that one denomination that's chosen
branches dynamically changing, at most n branches
If there's duplication in denomination, sort the array and add a condition check to skip.
TC: target = n, # of coin denomination = m O(n^m) worst
SC: m on stack, m on heap(cur) O(m)
public List<List<Integer>> combinations(int target, int[] coins) {
List<List<Integer>> res = new ArrayList<>();
List<Integer> cur = new ArrayList<>(); //prefix solution
helper(target, coins, 0, cur, res);
return res;
}
private void helper(int remain, int[] coins, int index, List<Integer> cur, List<List<Integer>> res) {
//base case: terminate when considering the last denomination
if (index == coins.length - 1) {
if (remain % coins[coins.length - 1] == 0) {
cur.add(remain / coins[coins.length - 1]);
res.add(new ArrayList<Integer>(cur)); // deep copy
cur.remove(cur.size() - 1);
}
return;
}
//for denomination 'coins[index]', pick 0 ~ (remain / coins[index]) amount
// i: amount picked
for (int i = 0; i <= remain / coins[index]; i++) {
cur.add(i)
helper(remain - i * coins[index], coins, index + 1, cur, res);
cur.remove(cur.size() - 1)
}
}
Last updated
Was this helpful?