1. # 给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回
  2. # -1。
  3. #
  4. # 你可以认为每种硬币的数量是无限的。
  5. #
  6. #
  7. #
  8. # 示例 1:
  9. #
  10. #
  11. # 输入:coins = [1, 2, 5], amount = 11
  12. # 输出:3
  13. # 解释:11 = 5 + 5 + 1
  14. #
  15. # 示例 2:
  16. #
  17. #
  18. # 输入:coins = [2], amount = 3
  19. # 输出:-1
  20. #
  21. # 示例 3:
  22. #
  23. #
  24. # 输入:coins = [1], amount = 0
  25. # 输出:0
  26. #
  27. #
  28. # 示例 4:
  29. #
  30. #
  31. # 输入:coins = [1], amount = 1
  32. # 输出:1
  33. #
  34. #
  35. # 示例 5:
  36. #
  37. #
  38. # 输入:coins = [1], amount = 2
  39. # 输出:2
  40. #
  41. #
  42. #
  43. #
  44. # 提示:
  45. #
  46. #
  47. # 1 <= coins.length <= 12
  48. # 1 <= coins[i] <= 231 - 1
  49. # 0 <= amount <= 104
  50. #
  51. # Related Topics 动态规划
  52. # 👍 967 👎 0
  53. # leetcode submit region begin(Prohibit modification and deletion)
  54. class Solution(object):
  55. def __init__(self):
  56. self.cache = dict()
  57. def coinChange(self, coins, amount):
  58. """
  59. :type coins: List[int]
  60. :type amount: int
  61. :rtype: int
  62. """
  63. # base case
  64. if amount == 0:
  65. return 0
  66. if amount < 0:
  67. return -1
  68. # 缓存
  69. if amount in self.cache:
  70. return self.cache[amount]
  71. res = float("inf")
  72. for coin in coins:
  73. pre = self.coinChange(coins, amount - coin)
  74. self.cache[amount - coin] = pre
  75. if pre == -1:
  76. continue
  77. res = min(res, 1 + pre)
  78. return -1 if res == float("inf") else res
  79. # leetcode submit region end(Prohibit modification and deletion)
  80. print(Solution().coinChange([11, 12], 25))

自底向上(推荐)

  1. # leetcode submit region begin(Prohibit modification and deletion)
  2. class Solution(object):
  3. def __init__(self):
  4. self.cache = dict()
  5. def coinChange(self, coins, amount):
  6. """
  7. :type coins: List[int]
  8. :type amount: int
  9. :rtype: int
  10. """
  11. dp = [float("inf") for x in range(amount + 1)]
  12. dp[0] = 0
  13. for i in range(amount + 1):
  14. for coin in coins:
  15. if i < coin:
  16. continue
  17. dp[i] = min(dp[i], 1 + dp[i - coin])
  18. return dp[amount] if dp[amount] != float("inf") else -1
  19. # leetcode submit region end(Prohibit modification and deletion)
  20. print(Solution().coinChange([11, 12], 2000002))