518. Coin Change II
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
Example 2:
Input: amount = 3, coins = [2]
Output: 0
Explanation: the amount of 3 cannot be made up just with coins of 2.
Example 3:
Constraints:
1 <= coins.length <= 300
1 <= coins[i] <= 5000
- All the values of
coins
are unique. 0 <= amount <= 5000
Solution:
class Solution {
int[][] dp;
public int change(int amount, int[] coins) {
dp = new int[coins.length][amount + 1];
// dp[i][j] represents the number of ways to make up amount j using the first i coin
/*
a/c 0 1 2 3 4 5 6
0 -1 -1 -1 -1 -1 -1 -1
1 -1 -1 -1 -1 -1 -1 -1
2 -1 -1 -1 -1 -1 -1 -1
*/
for (int i = 0; i < coins.length; i++){
for (int j = 0; j < amount + 1; j++){
dp[i][j] = -1;
}
}
int index = coins.length - 1;
return helper(amount, coins, index);
}
private int helper(int amount, int[] coins, int index){
if (amount == 0){
return 1;
}
//// If amount is 0, there is one way to achieve it (use no coins)
if (index == -1){
return 0;
}
//// If no coins left and amount is not 0, there is no way to achieve the amount
if (dp[index][amount] != -1){
return dp[index][amount];
}
// Include the coin if its value is less than or equal to amount, and exclude it
if (coins[index] <= amount){
dp[index][amount] = helper(amount - coins[index], coins, index) + helper(amount, coins, index - 1);
return dp[index][amount];
}else{
dp[index][amount] = helper(amount, coins, index - 1);
return dp[index][amount];
}
}
}
// TC: O(n*m)
// SC: O(n*n)