Solution 1
- TimeO(n * m)
- SpaceO(n)
Where, n is the amount, m is number of coins.
This is a Top-Down approach, a recursive solution with memoization.
This is more intuitive to think of than Bottom-Up approach.
Python
class Solution:
'''
Time Complexity: O(n * m)
Space Complexity: O(n)
Where, n is the amount, m is number of coins.
This is a Top-Down approach, a recursive solution with memoization.
This is more intuitive to think of than Bottom-Up approach.
'''
def coinChange(self, coins: List[int], amount: int) -> int:
cache = {0: 0}
def dfs(target):
if target in cache:
return cache[target]
if target < 0:
return -1
res = float('inf') # Can use `amount + 1` instead of `float('inf')` because max coins needed will be amount (all 1s) if "1" coin exists
for coin in coins:
tres = dfs(target-coin)
if tres > -1:
res = min(res, tres+1)
if res == float('inf'): # Can use `amount + 1` instead of `float('inf')`
cache[target] = -1
return -1
cache[target] = res
return res
return dfs(amount)Solution 2
- TimeO(n * m)
- SpaceO(n)
Where, n is the amount, m is number of coins.
This is a Bottom-Up approach, an iterative solution with Dynamic Programming.
Python
class Solution:
'''
Time Complexity: O(n * m)
Space Complexity: O(n)
Where, n is the amount, m is number of coins.
This is a Bottom-Up approach, an iterative solution with Dynamic Programming.
'''
def coinChange(self, coins: List[int], amount: int) -> int:
dp = [amount + 1] * (amount + 1)
dp[0] = 0
for a in range(1, amount + 1):
for c in coins:
if a - c >= 0:
dp[a] = min(dp[a], 1 + dp[a - c])
return dp[amount] if dp[amount] != amount + 1 else -1