1. Recursion

class Solution:
    def coinChange(self, coins: List[int], amount: int) -> int:

        def dfs(amount):
            if amount == 0:
                return 0

            res = 1e9
            for coin in coins:
                if amount - coin >= 0:
                    res = min(res, 1 + dfs(amount - coin))
            return res

        minCoins = dfs(amount)
        return -1 if minCoins >= 1e9 else minCoins

Time & Space Complexity

  • Time complexity: O(nt)O(n ^ t)
  • Space complexity: O(t)O(t)

Where nn is the length of the array coinscoins and tt is the given amountamount.


2. Dynamic Programming (Top-Down)

class Solution:
    def coinChange(self, coins: List[int], amount: int) -> int:
        memo = {}

        def dfs(amount):
            if amount == 0:
                return 0
            if amount in memo:
                return memo[amount]

            res = 1e9
            for coin in coins:
                if amount - coin >= 0:
                    res = min(res, 1 + dfs(amount - coin))

            memo[amount] = res
            return res

        minCoins = dfs(amount)
        return -1 if minCoins >= 1e9 else minCoins

Time & Space Complexity

  • Time complexity: O(nt)O(n * t)
  • Space complexity: O(t)O(t)

Where nn is the length of the array coinscoins and tt is the given amountamount.


3. Dynamic Programming (Bottom-Up)

class Solution:
    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

Time & Space Complexity

  • Time complexity: O(nt)O(n * t)
  • Space complexity: O(t)O(t)

Where nn is the length of the array coinscoins and tt is the given amountamount.


class Solution:
    def coinChange(self, coins: List[int], amount: int) -> int:
        if amount == 0:
            return 0

        q = deque([0])
        seen = [False] * (amount + 1)
        seen[0] = True
        res = 0

        while q:
            res += 1
            for _ in range(len(q)):
                cur = q.popleft()
                for coin in coins:
                    nxt = cur + coin
                    if nxt == amount:
                        return res
                    if nxt > amount or seen[nxt]:
                        continue
                    seen[nxt] = True
                    q.append(nxt)

        return -1

Time & Space Complexity

  • Time complexity: O(nt)O(n * t)
  • Space complexity: O(t)O(t)

Where nn is the length of the array coinscoins and tt is the given amountamount.