题目描述:
这题和做题昨天类似,区别在于它是需要用最小的 钱的组合去打成目标金额
举个栗子:
输入:目标金额 6 和 面额数组[ 1, 2, 4 ]
我们需要用最少的面额组合去达成这个目标金额,所以就不能像上一题一样,使用6个一块钱,那就不是最小硬币使用了。我们最佳的组合是 2 + 4 只用了两张钱,达成了我们的目标金额。
解题思路:
同样我们也需要创建一个数组去存储当前面额达到目标金额所需要的张数,数组的长度是 目标金额 + 1(这其实是为了代码的可读性做考量)。我们将这个数组命名成nums
1. 所以现在我们有一个数组 nums = [ 0, 0, 0, 0, 0, 0, 0 ],数组长度为7,下标索引对应的是目标金额。1代表目标金额是1。
2. 然后我们需要开始计算当前面额达到目标金额所需要的张数是多少?
首先我们需要判断当前面额是否小于目标金额,因为只有小于目标金额我们才能拼凑出它。当当前面额小于目标金额的时候我们开始计算,我们从1开始,因为达成0不需要任何面额。
我们第一个面额是1,1 小于等于 1,所以我们用1 - 1 = 0,等号左边的减数是1,因此我们需要一枚一元的钱,更新数组,[ 0, 1, 0, 0, 0, 0, 0 ]。我们接下来到目标金额2,2 - 1 = 1,等号左右两边都有一个1 所以 1 + 1等于 2,因此我们需要2枚一元硬币。接下来就以此类推了。因为3 - 1 = 2,我们知道2的情况,所以 1 + 2 = 3。因此我们最终的数组如图所示。

后面的面额也是同样输入进来,然后我们做同样的判断,因此如图,在不同面额的时候我们得到了不同的操作数。在这里再提一下,当面额为2的时候,我们怎么得到5。因为5 - 2 = 3 我们知道面额为2需要一张,面额3的时候我们知道面额3的情况,因为在更新5之前我们更新了3,所以只要用3的情况加上一张2,也就是 2 + 1 = 3,所以在面额为2时达成目标金额5需要三张钱。

最后我们只需要在更新数组的时候和前面所需要的操作数做对比,更新最小的那个操作数就行了。因此我们可以得到伪代码如图
伪代码中的 1 + nums[ 目标金额 - 当前面额] 中的1代表的是当前面额的数量, 5 - 2 中的2,我们需要一张2面额的钱。

时间复杂度和空间复杂度分析:
空间复杂度时 目标金额的大小 n,因此时O(n)
时间复杂度是,面额数组的大小d,和目标金额的大小n,这两个数组是个我们需要嵌套循环,所以是O(n* d)
代码部分
