Coin Change

Medium

完全背包问题:不限个数 + 目标装满 + 求最少硬币数

You are given coins of different denominations and a total amount of money amount. Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return-1.

Example 1:

Input: 
coins = 
[1, 2, 5]
, amount = 
11
Output: 
3
Explanation:
 11 = 5 + 5 + 1

Example 2:

Input: 
coins = 
[2]
, amount = 
3
Output: 
-1

Note: You may assume that you have an infinite number of each kind of coin.

Analysis

背包类问题:

  • 每个元素可以取任意次;

  • 只问最小的硬币数,就类似于 climbing stairs,只靠 sum 一个维度就可以了,但是循环依然是两层。

关于内外循环的顺序:此题中两者皆可。外循环为金额更直观一些。

Solution

以金额为外循环 (Preferred)

初始dp[i] = MAX; 其中 MAX = amount + 1, i = 1, ..., amount 是有前提假设的,即coins中最小的元素为1,这样最多有amount个硬币

硬币面值为外循环

Another implementation

因为这里int MAX = Integer.MAX_VALUE;,要注意检查dp[j - coins[i]] != MAX,否则会整型溢出。

LeetCode Official Solution - Dynamic Programming

DFS Recursive + Memoization

F(S) - minimum number of coins needed to make change for amount S using coin denominations [c0 … cn−1]

Then:

Recursion Search Tree: // [1, 2, 5] target = 6

// rec (6) // rec(6 - 1), rec(6 - 2), rec(6 - 5) // rec(6 - 1 - 1), rec(6 - 1 - 2), rec(6 - 1 - 5), rec(6 - 2 - 1), rec(6 - 5 - 1) // ... // rec(0) = 0

搜索树有许多重复的subproblem需要进行剪枝。

minCount[] - A memo to record visited & min coins for amount i

  • if minCount[i] == -1, visited, but not reachable

  • if minCount[i] == MAX, not visited

About repetition of elements: 循环的次序

By (@yuxiangmusic),

The difference is that if you updatedpwhile:

  • increasing i then the previous partial result dp[i - coin] is the result that has considered coin already

  • decreasing i then the previous partial result dp[i - coin] is the result that has not considered coin yet

Reference

https://leetcode.com/problems/coin-change/solution/

@mnmunknown - 8/2,背包问题

Last updated

Was this helpful?