算法322. 零钱兑换

题目

给你一个整数数组 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

题解

python 复制代码
class Solution:
    def coinChange(self, coins: List[int], amount: int) -> int:
        @cache
        # 完全背包问题
        # dfs(i, c) = 使用硬币种类 coins[0], coins[1], ..., coins[i]来凑出恰好金额c所需的最少硬币数量
        # i:当前可以考虑的硬币种类的最大索引
			# i = 0 表示只能使用第一种硬币 coins[0]
			# i = 2 表示可以使用前三种硬币 coins[0], coins[1], coins[2]

		# c:需要凑出的剩余目标金额
        def dfs(i:int,c:int)->int:
        	# 没有硬币可用(i < 0),但金额也刚好为0,说明之前的硬币选择已经完美凑出了目标金额
            if i < 0:
                return 0 if c == 0 else inf
            # 不选该硬币
            if c < coins[i]:
                return dfs(i-1,c)
            
            # 不选 vs 选
            # 这里覆盖了没有任何一种硬币组合能组成总金额的情况,此时这里会返回inf
            return min(dfs(i-1,c),dfs(i,c-coins[i])+1)
        
        ans = dfs(len(coins) - 1,amount)
        return ans if ans<inf else -1

复杂度分析

  • 时间复杂度:O(n⋅amount),其中 n 为 coins 的长度。
  • 空间复杂度:O(n⋅amount)。
相关推荐
hh随便起个名6 小时前
力扣二叉树的三种遍历
javascript·数据结构·算法·leetcode
Dingdangcat867 小时前
城市交通多目标检测系统:YOLO11-MAN-FasterCGLU算法优化与实战应用_3
算法·目标检测·目标跟踪
tang&8 小时前
滑动窗口:双指针的优雅舞步,征服连续区间问题的利器
数据结构·算法·哈希算法·滑动窗口
拼命鼠鼠8 小时前
【算法】矩阵链乘法的动态规划算法
算法·矩阵·动态规划
LYFlied8 小时前
【每日算法】LeetCode 17. 电话号码的字母组合
前端·算法·leetcode·面试·职场和发展
式5169 小时前
线性代数(八)非齐次方程组的解的结构
线性代数·算法·机器学习
橘颂TA9 小时前
【剑斩OFFER】算法的暴力美学——翻转对
算法·排序算法·结构与算法
叠叠乐9 小时前
robot_state_publisher 参数
java·前端·算法
hweiyu0010 小时前
排序算法:冒泡排序
算法·排序算法
brave and determined10 小时前
CANN训练营 学习(day9)昇腾AscendC算子开发实战:从零到性能冠军
人工智能·算法·机器学习·ai·开发环境·算子开发·昇腾ai