Date and Time: Aug 23, 2024, 0:36 (EST)
Link: https://leetcode.com/problems/coin-change/
You are given an integer array coins
representing coins of different denominations and an integer amount representing a total amount
of money.
Return 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
.
You may assume that you have an infinite number of each kind of coin.
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
Example 3:
Input: coins = [1], amount = 0
Output: 0
-
1 <= coins.length <= 12
-
1 <= coins[i] <= 2^{31} - 1
-
0 <= amount <= 10^4
We can use dp bottom-up method to store the value of each amount a
from 0
to amount
with the minimum number of coins we need to achieve for each a
.
-
initialize
dp
with a biggest numberamount + 1
with size(amount + 1)
, because the base case to achieveamount = 0
, we need0
coin. So we adddp[0] = 0
. -
Start building
dp
fromrange(1, amount + 1)
, we try eachc
fromcoins
, if current amounta - c >= 0
, we can updatedp[a] = min(dp[a], 1 + dp[a-c])
, which means current coinc
can be used, and we updatedp[a]
by the recurrence relation above, we assume we take this coinc
, how many coins to take for the difference, so we have1 + dp[a-c]
. -
Finally, return the last element in
dp[amount]
, but we need to make sure we have changed thedp[amount]
, otherwise, we should return-1
.
class Solution:
def coinChange(self, coins: List[int], amount: int) -> int:
# 0 1 2 3 4 5 6 7 8 9 10 11
# 0 1 1 2 2 1 2 2 3 3 2 3
# Build a dp table with [0, amount]
# For a in amount, we try every denomination, if one fits, we assume we use this coin + the difference dp[a-c]
# If a - coin >= 0 means this coin makes contribution
# Otherwise, we don't use this coin
# TC: O(m * n), SC: O(m), n for len(coins), m for range(amount)
dp = [amount+1] * (amount+1) # Set it big
dp[0] = 0
for a in range(1, amount+1):
for c in coins:
if a - c >= 0:
# If we take this coin + coins from prev
dp[a] = min(dp[a], 1 + dp[a-c])
return dp[-1] if dp[-1] != amount + 1 else -1
Time Complexity: n
is len(coins)
, m
is amount
. Because each value of amount
we try all the coins.
Space Complexity: