You are given an integer array coins representing coins of different denominations and an integer amount representing a total amount of money.
Return the number of combinations that make up that amount. If that amount of money cannot be made up by any combination of the coins, return 0.
You may assume that you have an infinite number of each kind of coin.
The answer is guaranteed to fit into a signed 32-bit integer.
Example 1
Input: amount = 5, coins = [1,2,5]
Output: 4
Explanation: there are four ways to make up the amount:
5=5
5=2+2+1
5=2+1+1+1
5=1+1+1+1+1
Constraints:
1 <= coins.length <= 3001 <= coins[i] <= 5000- All the values of
coinsare unique. 0 <= amount <= 5000
- It's a fairly easy question, but it is an excellent introduction to a faily important algorithmic pattern, i.e., Dynamic Programming (DP).
- Assume you worked on DP problems before, you are probably familiar with the concepts likes "base case", "state" and "formula", let's forget about that for now and see how we can achieve that.
- Btw, when you see a statement like "return the number of combinations ...", that's a good signal to try DP first.
- Let's see we can do for this problem.
- So we want to find out how to make
amountwith different uniquecoins. - Let's take the first example, where
coins = [1,2,5]andamount = 5. - So to make a
5, we can grab a coin5, that's one way and only way with a coin5. Easy. - Is there another way to make
5though? Yep, since we have a coin1, if we can make a4inXnumber of ways, then we know we can get a5inXmore number of ways. - Similarly, since we have a coin
2, if we can make a3inYnumber of ways, we know we can get a5inYmore number of ways. - I believe you probably spot a pattern now, which is, if we define
dp[amount]to be "number of ways to getamount", thendp[amount] = dp[amount] + dp[amount - coin] for coin in coins. - And how do we get
dp[amount - coin]? Actually, it's the same question. Assumeamount - coin = i, we havedp[i] = dp[i] + dp[i - coin] for coin in coins. - And initially,
dpshould be initialized with all0s, exceptdp[0] = 1, because that's what we have at the beginning, so no surprise. - At last we should return
dp[amount], that's it. - It should be fairly easy now to write the code. Let me know if it does not make sense to you.
- Thanks for reading, :).
// dp[i]: different ways to make up amount i
// dp[i] = dp[i] + dp[i - coin] for coin in coins
const change = function(amount, coins) {
const dp = Array(amount + 1).fill(0);
dp[0] = 1;
for (const coin of coins) {
for (let i = coin; i <= amount; i += 1) {
dp[i] += dp[i - coin];
}
}
return dp[dp.length - 1];
};