Skip to content

Latest commit

 

History

History
122 lines (93 loc) · 2.83 KB

0322-coin-change.adoc

File metadata and controls

122 lines (93 loc) · 2.83 KB

322. 零钱兑换

给你一个整数数组 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. 这种找路径,找方法的题一般可以使用回溯法来解决,回溯法也可以说是树形图法,解题的时候使用类似于树状图的结构,使用 自顶而下 的方法。

  2. 而在回溯法中,如果含有很多的重复的计算的时候,就可以使用记忆化的搜索,将可能出现的重复计算大状态使用一个数组来保存其值,在进行重复的计算的时候,就可以直接的调用数组中的值,较少了不必要的递归。

  3. 使用了记忆化搜索后,一般还可以进行优化,在记忆化搜索的基础上,变成 自底而上 的动态规划。

{image_attr}
{image_attr}
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
{image_attr}
一刷
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]

思考题

  1. 如何把动态规划代码写得更简洁一些?

  2. 如何使用自底向上方法来实现一遍动态规划?