class Solution:
def change(self, amount: int, coins: List[int]) -> int:
"""tc O(KN) sc O(KN)
main idea: Top Down
dp[i][j]: ways of COMBINATION to fill j amount with first time using coins[i-1]
"""
n = len(coins)
dp = [[0 for x in range(amount+1)] for _ in range(n+1)]
# base case
dp[0][0] = 1
for i in range(1,n+1):
dp[i][0] = 1
for i in range(1,len(coins)+1):
for j in range(1,amount+1):
if j >= coins[i-1]:
# here use dp[i][j-coins[i-1]] instead of dp[i-1][j-coins[i-1]]
# because it includes repeatedly using coin[i-1]
dp[i][j] = dp[i-1][j] + dp[i][j-coins[i-1]]
else:
dp[i][j] = dp[i-1][j]
return dp[n][amount]
Save space
class Solution:
def change(self, amount: int, coins: List[int]) -> int:
""" tc O(Amount*len(coins)) sc O(amount)s
main idea: Top Down
dp[i][j]: ways of COMBINATION to fill j amount with first time using coins[i-1]
"""
n = len(coins)
dp = [0 for x in range(amount+1)]
dp[0] =1
for i in range(1,n+1):
for j in range(1,amount+1):
dp[j] = dp[j] + (dp[j-coins[i-1]] if j >= coins[i-1] else 0)
return dp[amount]
here note the order can not be reversed since order of coin does not matter here. However, in LC 377. Combination Sum IV for loop need to be the other way around since order matter there .