LeetCode -- Coin Change
Question:
You are given coins of different denominations and a total amount of money amount. Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1
.
Example 1:
coins = [1, 2, 5]
, amount = 11
return 3
(11 = 5 + 5 + 1)
Example 2:
coins = [2]
, amount = 3
return -1
.
Note:
You may assume that you have an infinite number of each kind of coin.
Analysis:
给你不同金额的硬币,和一个总的金额。写一个算法,可以得出使用最少数目的硬币便可得到该给定金额。如果给定的金额不能由这些硬币得到,则返回-1.
思路:
由于前面有了一些关于动态规划的分析,所以这个一看就是使用DP。http://www.cnblogs.com/little-YTMM/p/5372680.html 与前面的例子不同的是,前面是求得到指定金额的不同纸币的组合数目,而这一次是得到凑到该金额的最小数目。但是总体思路是一样的,无非一个用Max,一个用Min。
例如对于上面的Example 1 .对于硬币5,可能最终方案中包含,可能不包含。所以dp[5][11] = Min(dp[5][6], dp[2][11]),即取两种来源中使用的coin数较少的那个。同样的,我们可以用滚动数组来解决。
代码如下:
public class Solution { public int coinChange(int[] coins, int amount) { int[] dp = new int[amount+1]; int inital = 0x7ffffffe; for(int i=1; i<dp.length; i++) dp[i] = inital; for(int i=0; i<dp.length; i++) { for(int j=0; j<coins.length; j++) { if(i + coins[j] <= amount) dp[i+coins[j]] = Math.min(dp[i+coins[j]], dp[i] + 1); } } return dp[amount] == inital ? -1 : dp[amount]; } }
这里有一点巧妙的是,因为有可能对于一个给定金额amount,无法用给定的coin得到解决方案,因此我们首先将所有的dp都设为一个指定的最大值,如果最后没有更新,就说明没有解决方案,否则返回coin数目即可。