给你一个整数数组 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
动态规划:
func coinChange(coins []int, amount int) int {
// dp[j] 含义:凑足总金额为 j 所需钱币最少的个数为 dp[j]
dp := make([]int, amount+1)
// 初始化 dp:满足总金额为 0 的钱币个数一定是 0
dp[0] = 0
// 所需钱币最少个数都初始化为一个 int 最大值
for j := 1; j <= amount; j++ {
dp[j] = math.MaxInt
}
// 遍历顺序不重要,这里先遍历物品
for i := 0; i < len(coins); i++ {
// 遍历背包
for j := coins[i]; j <= amount; j++ {
if dp[j-coins[i]] != math.MaxInt {
// 状态转移公式
dp[j] = min(dp[j], dp[j-coins[i]]+1)
}
}
}
// 如果所需最少个数还是 int 最大值,说明没有合适的钱币,直接返回 -1 即可
if dp[amount] == math.MaxInt {
return -1
}
return dp[amount]
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
评论前必须登录!
注册