一、题目描述
给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。
计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。
你可以认为每种硬币的数量是无限的。
示例 1:
输入:coins = [1, 2, 5], amount = 11
输出:3
解释:11 = 5 + 5 + 1
示例 2:
输入:coins = [2], amount = 3
输出:-1
示例 3:
输入:coins = [1], amount = 0
输出:0
提示:
1 <= coins.length <= 12
1 <= coins[i] <= 231 – 1
0 <= amount <= 104
二、思路讲解
以示例1为例,我们设dp[i]为目标面额i的最小钱币数,那么我们所求的就是dp[11]。假如我们知道dp[10],那么再加一个金币是dp[11]了;同理,我们如果知道dp[6],那么再加一个面额为5的金币也是dp[11]了;我们如果知道dp[9],再加一个面额为2的金币也是dp[11]了。
所以,dp[11] 实际上就是dp[10]+1,或者dp[9]+1,或者dp[6]+1,具体取哪个值呢?就看哪个值小,因为我们要求最小金币数。故:
min {dp[i-可能面额1], dp[i-可能面额2] , dp[i-可能面额3] ……} +1 i > 0
dp[i] = 0 i = 0
-1 i < 0
三、Java代码实现
class Solution {
public int coinChange(int[] coins, int amount) {
int []dp = new int[amount+1];
//初始化为amount+1, 便于后面min比较
for(int i=1; i<amount+1; i++) {
dp[i] = amount+1;
}
dp[0] = 0;
//外层循环枚举所有可能的面值
for(int i=0; i<amount+1; i++) {
//内层循环求出该面值下所有可能选择的最小值
for(int coin : coins) {
//过滤掉不可能的情况
if(i<coin) {
continue;
}
dp[i] = Math.min(dp[i], dp[i-coin]+1);
}
}
return (dp[amount]==(amount+1)) ? (-1) : dp[amount];
}
}
参考:动态规划套路详解
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/124976.html