给你一个整数数组 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
解题思路
-
这种找路径,找方法的题一般可以使用回溯法来解决,回溯法也可以说是树形图法,解题的时候使用类似于树状图的结构,使用 自顶而下 的方法。
-
而在回溯法中,如果含有很多的重复的计算的时候,就可以使用记忆化的搜索,将可能出现的重复计算大状态使用一个数组来保存其值,在进行重复的计算的时候,就可以直接的调用数组中的值,较少了不必要的递归。
-
使用了记忆化搜索后,一般还可以进行优化,在记忆化搜索的基础上,变成 自底而上 的动态规划。
F(3) =min(F(3−c1),F(3−c 2),F(3−c3))+1
=min(F(3−1),F(3−2),F(3−3))+1
=min(F(2),F(1),F(0))+1
=min(1,1,0)+1
=1
- 一刷
-
link:{sourcedir}/_0322_CoinChange.java[role=include]
- 二刷(暴力穷举)
-
link:{sourcedir}/_0322_CoinChange_2.java[role=include]
- 二刷(动态规划(莫名其妙解法))
-
link:{sourcedir}/_0322_CoinChange_21.java[role=include]
- 二刷(动态规划)
-
link:{sourcedir}/_0322_CoinChange_22.java[role=include]
- 三刷(动态规划)
-
link:{sourcedir}/_0322_CoinChange_3.java[role=include]