## 518. Coin Change 2

You are given coins of different denominations and a total amount of money. Write a function to compute the number of combinations that make up that amount. You may assume that you have infinite number of each kind of coin.

Note:You can assume that

• 0 <= amount <= 5000
• 1 <= coin <= 5000
• the number of coins is less than 500
• the answer is guaranteed to fit into signed 32-bit integer

Thoughts:

1. `dp[i][j]`: the number of combinations to make up amount `j`by using the first `i`types of coins`State transition`:

1. not using the `i`th coin, only using the first `i-1`coins to make up amount `j`, then we have `dp[i-1][j]` ways.
2. using the `i`th coin, since we can use unlimited same coin, we need to know how many way to make up amount `j - coins[i]`by using first `i`coins( including `i`th), which is `dp[i][j-coins[i]]`
3. `Initialization`:`dp[i][0] = 1`
2. `dp[i][j]`only rely on `dp[i-1][j]`and `dp[i][j-coins[i]]`, then we can optimize the space by only using one-dimension array.

Code: 2D DP: O(K * N), S: O(K * N)

``````class Solution {
public int change(int amount, int[] coins) {
int[][] dp = new int[coins.length+1][amount+1];
dp[0][0] = 1;

for (int i = 1; i <= coins.length; i++) {
dp[i][0] = 1;
for (int j = 1; j <= amount; j++) {
dp[i][j] = dp[i-1][j] + (j >= coins[i-1] ? dp[i][j-coins[i-1]] : 0);
}
}
return dp[coins.length][amount];
}
}
``````

Code: 1D DP: O(K * N), S: O(N)

``````class Solution {
public int change(int amount, int[] coins) {
if(amount < 0) return 0;
int dp[] = new int [amount + 1];
dp[0] = 1;
for(int coin: coins){
for(int i = coin; i <= amount ; i++){
dp[i]+= dp[i - coin];
}
}

return dp[amount];
}
}
``````