322. Coin Change
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.Functional Interface:
int coinChange(vector<int>& coins, int amount)
已知我们有n种面额的钱币,从小到大依次存入coin中,之后我们一共要凑够amount的金额,并且要使总钱币的个数最小;若是不存在,则返回-1。
这道题实际上是一道动态规划的找零问题。我们想求总金额为amount的最小钱币数,也就是要求amount-小于amount的最大面额的最小钱币数。所以我们可以从最小金额(1,对于0来说,最小钱币数永远是0)开始求解最小钱币数,通过循环,依次求解金额(i)为1~amount的最小钱币数。对于每一个金额,我们都有
result[i]=min(result[i],result[i−coins[j]]+1)
r
e
s
u
l
t
[
i
]
=
m
i
n
(
r
e
s
u
l
t
[
i
]
,
r
e
s
u
l
t
[
i
−
c
o
i
n
s
[
j
]
]
+
1
)
其中i是金额,j是指第j种面额,result是存储各个金额的最小钱币数。
对于不存在在的情况,我们则将其设为一个很大的值(infinity)。由上述公式可知,若是某种金额不存在找零的情况,那么其result[i-coins[j]]必然会是infinite,因为它也不存在找零情况。也就是说,所有不存在找零的金额,它对应的result中存储的值一定为infinity,那么必然有当当我们求解完amount的最小钱币数时,若是为infinity,则意味着改金额不存在找零的情况,返回-1,其余情况则返回求得的最小钱币数。
参考代码如下:
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
int infinity = 2*amount;
vector<int> result(amount+1, infinity);
result[0] = 0;
for(int i = 1; i <= amount; i++) {
for(int j = 0; j < coins.size(); j++) {
if(i >= coins[j]) {
int min = result[i];
if(result[i - coins[j]] + 1 < min)
min = result[i - coins[j]] + 1;
result[i] = min;
}
}
}
if(result[amount] > amount)
return -1;
else
return result[amount];
}
};