You may assume that you have an infinite number of each kind of coin.
Copy **Input:** coins = [1,2,5], amount = 11
**Output:** 3
**Explanation:** 11 = 5 + 5 + 1
Copy **Input:** coins = [2], amount = 3
**Output:** -1
Copy **Input:** coins = [1], amount = 0
**Output:** 0
Copy **Input:** coins = [1], amount = 1
**Output:** 1
Copy **Input:** coins = [1], amount = 2
**Output:** 2
Copy class Solution {
public int coinChange ( int [] coins , int amount) {
// edge cases
if (coins == null || coins . length == 0 || amount <= 0 ) return 0 ;
// DP
int [] dp = new int [amount + 1 ];
// init
for ( int i : coins) {
if (i <= amount) dp[i] = 1 ;
}
// iterate
for ( int i = 1 ; i <= amount; i ++ ) {
if (dp[i] != 0 ) continue ;
int min = Integer . MAX_VALUE ;
for ( int j = 0 ; j < coins . length ; j ++ ) {
int prev = i - coins[j];
if (prev <= 0 || dp[prev] == - 1 ) continue ;
min = Math . min (min , dp[prev] + 1 );
}
dp[i] = min == Integer . MAX_VALUE ? - 1 : min;
}
// res
return dp[amount];
}
}
/*
state: dp[i] means fewest coins for i amount
func: dp[i], iterate coins, i - coin, get minimun
init: dp[coin] = 1
result: last one
*/
Copy class Solution {
public int coinChange ( int [] coins , int amount) {
// edge cases
if (coins == null || coins . length == 0 || amount <= 0 ) return 0 ;
int [] dp = new int [amount + 1 ];
// init
Arrays . fill (dp , amount + 1 );
dp[ 0 ] = 0 ;
// iterate
for ( int i = 1 ; i <= amount; i ++ ) {
for ( int j = 0 ; j < coins . length ; j ++ ) {
if (coins[j] <= i) {
dp[i] = Math . min (dp[i] , dp[i - coins[j]] + 1 );
}
}
}
// res
return dp[amount] > amount ? - 1 : dp[amount];
}
}