Coin Change
You're given an array coins of distinct coin denominations and an integer amount. You have an unlimited supply of every denomination. Return the fewest coins whose values add up to exactly amount, or -1 if no combination of coins reaches it. An amount of 0 needs 0 coins.
Examples
coins = [1,2,5], amount = 11 returns 3
5 + 5 + 1 = 11 uses three coins. Two coins top out at 5 + 5 = 10, so three is the minimum.
coins = [2], amount = 3 returns -1
Any number of 2s adds up to an even total, so 3 can never be reached.
coins = [1], amount = 0 returns 0
There is nothing to pay, so zero coins are needed.
Constraints
- 1 <= coins.length <= 12
- 0 <= amount <= 10^4
Hints
If you knew the minimum coins for every amount below the target, could you build up the answer?
Bottom-up DP: dp[a] = fewest coins needed to make amount a.
Initialize dp[0] = 0 and dp[a] = infinity for a > 0. For each amount a from 1 to amount, for each coin c <= a, set dp[a] = min(dp[a], dp[a - c] + 1). Return dp[amount] if finite, else -1.
Drill This: Your Approach First
Approach
Build a table dp where dp[a] is the fewest coins that make amount a. Start with dp[0] = 0 and every other entry at amount + 1, a stand-in for infinity, since no answer uses more than amount coins. For each a from 1 to amount, try every coin c <= a as the last coin: dp[a] = min(dp[a], dp[a - c] + 1). If dp[amount] is still above amount, it can't be made. O(amount * n) time, O(amount) space, n = number of coins.
Time
O(amount * n)
Space
O(amount)
Pitfall
Solutions
class Solution {
public int coinChange(int[] coins, int amount) {
int[] dp = new int[amount + 1];
Arrays.fill(dp, amount + 1);
dp[0] = 0;
for (int a = 1; a <= amount; a++) {
for (int c : coins) {
if (c <= a) dp[a] = Math.min(dp[a], dp[a - c] + 1);
}
}
return dp[amount] > amount ? -1 : dp[amount];
}
}class Solution:
def coinChange(self, coins, amount: int) -> int:
dp = [amount + 1] * (amount + 1)
dp[0] = 0
for a in range(1, amount + 1):
for c in coins:
if c <= a:
dp[a] = min(dp[a], dp[a - c] + 1)
return -1 if dp[amount] > amount else dp[amount]