- categories: Code, Interview Question, leetcode, Medium
- source: https://leetcode.com/problems/coin-change-ii
- topics: Dynamic Programming
You are given an integer array coins
representing coins of different denominations and an integer amount
representing a total amount of money.
Return the number of combinations that make up that amount. If that amount of money cannot be made up by any combination of the coins, return 0
.
You may assume that you have an infinite number of each kind of coin.
The answer is guaranteed to fit into a signed 32-bit integer.
Top-Down with memo
class Solution:
def change(self, amount: int, coins: List[int]) -> int:
N = len(coins)
memo = [[-1] * (amount + 1) for _ in range(N)]
def numberOfWays(i, amount):
if amount == 0:
return 1
if i == N:
return 0
if memo[i][amount] != -1:
return memo[i][amount]
if coins[i] > amount:
memo[i][amount] = numberOfWays(i + 1, amount)
else:
memo[i][amount] = numberOfWays(i, amount - coins[i]) + numberOfWays(i + 1, amount)
return memo[i][amount]
return numberOfWays(0, amount)
Bottom-Up Dynamic Programming
class Solution:
def change(self, amount: int, coins: List[int]) -> int:
N = len(coins)
dp = [[0] * (amount + 1) for _ in range(N)]
for i in range(N):
dp[i][0] = 1
for a in range(1, amount + 1):
dp[0][a] = dp[0][a - coins[0]]
for i in range(1, N):
for a in range(1, amount + 1):
if coins[i] <= a:
dp[i][a] = dp[i][a - coins[i]] + dp[i-1][a]
else:
dp[i][a] = dp[i-1][a]
return dp[N-1][amount]
Bottom-Up Dynamic Programming Optimized
class Solution:
def change(self, amount: int, coins: List[int]) -> int:
N = len(coins)
dp = [0] * (amount + 1)
dp[0] = 1
for i in range(N):
for a in range(coins[i], amount + 1):
dp[a] += dp[a - coins[i]]
return dp[amount]