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
Constraints:
1 <= coins.length <= 12
1 <= coins[i] <= 231 - 1
0 <= amount <= 104
`
Intuition
We need to try out all the coins. Let's get an example of amount 7
with value [1,3,5]
We have:
- If the amount is
1
:- We can use 1 coin
1
- We can use 1 coin
- If the amount is
2
:- We can use 2 coin
1
- We can use 2 coin
- If the amount is
3
:- We can use 3 coin
1
or 1 coin3
- We can use 3 coin
- If the amount is
4
:- We can use 4 coin
1
or 1 coin3
and 1 coin1
- We can use 4 coin
- If the amount is
5
:- We can use 5 coin
1
, 1 coin3
and 2 coin1
, or 1 coin5
- We can use 5 coin
The pattern is given coin[i]
, we have the following formula:
result_at_amount = 1 + result(amount - coin[i])
Explain:
- Given an amount (for example
5
), and a list of coins (1, 3, 5
) - Say if we pick a random coin to use (
3
), the number of way that we can form5
isresult = min_coin(5 - 3) + 1
+1
is because we are using the current coin so it add as the number of coins.min_coin(5-3) = min_coin(2)
since we used3
already we have to find the minimum coin to make2
.
Implementation
class App:
def coinChange(self, coins: List[int], amount: int) -> int:
dp = [float('inf') for _ in range(amount + 1)]
dp[0] = 0
for i in range(1, len(dp)):
for coin in coins:
if coin > i: continue
if coin == i:
dp[i] = 1
break
dp[i] = min(dp[i], dp[i - coin] + 1)
return dp[amount] if dp[amount] != float('inf') else -1
Time complexity: $O(amount \times coin)$
Space complexity: $O(n)$