Skip to content

Latest commit

 

History

History
99 lines (69 loc) · 2.45 KB

322-coin-change.md

File metadata and controls

99 lines (69 loc) · 2.45 KB

给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1

你可以认为每种硬币的数量是无限的。

 

示例 1:

输入:coins = [1, 2, 5], amount = 11
输出:3 
解释:11 = 5 + 5 + 1

示例 2:

输入:coins = [2], amount = 3
输出:-1

示例 3:

输入:coins = [1], amount = 0
输出:0

示例 4:

输入:coins = [1], amount = 1
输出:1

示例 5:

输入:coins = [1], amount = 2
输出:2

 

提示:

  • 1 <= coins.length <= 12
  • 1 <= coins[i] <= 231 - 1
  • 0 <= amount <= 104

Solutions

1. 暴力 + 缓存

设 f(n) 表示总和为 n 所需最少硬币数。直接暴力计算会超时。可以通过 cache 数组缓存 f(n) 结果。

class Solution:
    def coinChange(self, coins: List[int], amount: int) -> int:
        cache = [0] * (amount + 1)

        def f(n: int) -> int:
            if n == 0:
                return 0
            elif n < 0:
                return -1

            if cache[n] != 0:
                return cache[n]

            i = -1
            for c in coins:
                 v = f(n - c)
                 if v >= 0 and (i == -1 or v < i):
                     i = v + 1
            cache[n] = i
            return i

        return f(amount)

2. 动态规划

dp[i] 表示和为 i 时,需要的最小硬币数。

class Solution:
    def coinChange(self, coins: List[int], amount: int) -> int:
        dp = [0] + [float('inf')] * amount

        for c in coins:
            for i in range(c, amount + 1):
                dp[i] = min(dp[i], dp[i - c] + 1)
        
        return dp[-1] if dp[-1] != float('inf') else -1