首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

在硬币兑换类型的问题中将递归函数重构为迭代函数

在硬币兑换类型的问题中,我们通常需要计算用最少数量的硬币来兑换特定金额。递归方法是一种直观的解决方案,但可能会导致性能问题,特别是当金额较大时。迭代方法可以提供更好的性能。下面是将递归函数重构为迭代函数的详细解释和示例代码。

基础概念

  • 递归函数:函数直接或间接调用自身。
  • 迭代函数:使用循环结构来重复执行代码块。

相关优势

  • 性能提升:迭代方法通常比递归方法更快,因为它避免了函数调用的开销。
  • 避免栈溢出:递归深度过大可能导致栈溢出,而迭代方法不会遇到这个问题。

类型

  • 动态规划:一种常用的迭代方法,通过构建一个表来存储子问题的解。

应用场景

  • 硬币兑换问题:计算用最少数量的硬币兑换特定金额。
  • 背包问题:在给定容量的背包中放入最大价值的物品。

示例代码

假设我们有面值为 [1, 2, 5] 的硬币,目标是兑换金额为 11 的最少硬币数量。

递归方法

代码语言:txt
复制
def coin_change_recursive(coins, amount):
    if amount == 0:
        return 0
    if amount < 0:
        return float('inf')
    
    min_coins = float('inf')
    for coin in coins:
        result = coin_change_recursive(coins, amount - coin)
        if result != float('inf'):
            min_coins = min(min_coins, 1 + result)
    
    return min_coins

迭代方法(动态规划)

代码语言:txt
复制
def coin_change_iterative(coins, amount):
    # 初始化一个数组,dp[i] 表示兑换金额 i 所需的最少硬币数量
    dp = [float('inf')] * (amount + 1)
    dp[0] = 0  # 兑换金额 0 所需的硬币数量为 0
    
    for i in range(1, amount + 1):
        for coin in coins:
            if i - coin >= 0:
                dp[i] = min(dp[i], dp[i - coin] + 1)
    
    return dp[amount] if dp[amount] != float('inf') else -1

解释

  1. 初始化:创建一个长度为 amount + 1 的数组 dp,其中 dp[i] 表示兑换金额 i 所需的最少硬币数量。初始值设为 float('inf'),表示无法兑换。
  2. 基础情况dp[0] = 0,因为兑换金额 0 不需要任何硬币。
  3. 迭代更新:对于每个金额 i,遍历所有硬币面值,如果 i - coin >= 0,则更新 dp[i]min(dp[i], dp[i - coin] + 1)
  4. 返回结果:最终 dp[amount] 即为所需的最少硬币数量,如果仍为 float('inf'),则表示无法兑换。

应用场景

  • 金融系统:计算最少的货币兑换方案。
  • 游戏设计:在游戏中计算玩家需要的最少资源数量。

通过这种方式,我们可以有效地将递归问题转换为迭代问题,从而提高算法的性能和稳定性。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

一文带你入门动态规划

时间复杂度分析 二叉树的节点个数为指数级别,所求子问题的个数为O(2^n) 解决一个子问题的时间为O(1),因为值涉及到一个加法运算 故时间复杂度为 O(2^n) 消耗的内存与时间情况 ?...2.解法二,备忘录解法 在解法1中我们也介绍了暴力解法中存在的问题,及其问题存在的原因,那么在解法二中我们就通过加上备忘录的方式,来避免重复计算,这样可以大大提高解题的效率 代码 class Solution...编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。 你可以认为每种硬币的数量是无限的。...,amount为当前还剩的钱的数量,account为所用硬币的数量*/ public int findMin(int[] coins,int amount){ /*结束递归的条件...函数的含义来表现“状态”和选择 分析 1.最基本条件即 钱的金额为0的时候所需硬币数的0 2.状态就是钱的总金额,随着决策树一层一层决策,金额不断减少 3.发生状态变化的条件,每选择一枚硬币就减少一定的金额

46420

从零钱兑换再看动态规划的套路

在昨天的文章关于背包问题的一点发散[1]之后,有小伙伴说感觉跟LeetCode上一道题零钱兑换[2]很像,但是又好像有点不一样,简单的暴力递归跟缓存优化都能做出来,就是自下而上的方法不怎么有思路。...编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。...暴力递归无需过多分析了,无非是递归地做选择,选择硬币,然后选择硬币最少的那个方案。 咱们直接上递归代码,咱们主要思考分析工作在后期的算法优化上。...原谅我不会画表格,当我们只有面值为一的硬币时,我们要还多少钱就要多少个硬币。...当我们有面值为1,2两种的硬币时,当我们对5进行兑换时,不选择2这个面值的话,dp[0][5]是5,也就是我们需要5个面值为1的硬币,而dp[1][3]是是2,那这种情况兑换硬币就只要3个。

45520
  • 刷题第10篇:从完全平方到零钱兑换

    1、解决思路 不难看出,这道题目的状态转移方程为:nums[n] = Math.min(nums[n],nums[n - i* i] + 1),我们可以使用迭代的方法,不断的迭代调用之前每一个数字的平方数之和的最小个数...题目描述 简言之,使用最少的硬币数量,兑换成给定的金额。 1、解决思路 我们对比一下上面的完全平方数的题目,会惊奇的发现,其实两者在本质上是完全一样的呀!哈哈!...所以当时我们在遍历的时候,使用的代码是下面这样的: for(int i = 1 ; n >= i*i ; i++ ) 在这道题目中,题目已经明确给出了coins的集合类型,所以我们可以尝试着每次遍历给定的...coins集合: for(int coin:coins) 当我们更改遍历方式的时候,我们就需要额外考虑一种情况了,每次调用递归调用的时候,可能会出现一种target变为负值的情况,此时意味着target...的值小于coin的值,那么此时是无法兑换的。

    27420

    【LeetCode两题选手】算法类题目(8.7)

    },"val":3},"right":{"$ref":"4"},"val":2},"next":null,"right":{"$ref":"7"},"val":1} 解释:给定二叉树如图 A 所示,你的函数应该填充它的每个...使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。...编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。...思路:背包问题 首先想最少的硬币数,肯定是尽量取较大的硬币,能取一个则硬币数加一,取当前硬币的个数等于之前硬币个数加上当前这个硬币(也就是加1),但前提是之前硬币总价值加上当前这个硬币的价值不能超过总个数...,因此是一个动态规划问题。

    27620

    破解大厂最难算法命面试:动态规划之硬币兑换

    在动态规划问题中,有一个很常见的问题就是最少硬币兑换。假设当前有面额为1,2,5元的硬币,然后给你一定额度,要求你将额度兑换成等值硬币,并要求兑换硬币的数量要最少。...例如给定的额度为9元,那么兑换的方法有[5, 1, 1, 1, 1], [5,2,2], [2,2,2,1],很显然第二种兑换方法最好。 如果你了解前面描述的动态规划方法,那么这个问题的处理不难。...最顶层是要兑换的面额,然后根据不同硬币数值进行兑换后得到第二层,例如当前硬币数值为[1,2,5],面额为9,那么分别兑换硬币1,2,5后所得数额分别为8,7,4,接下来分别针对第二层3个节点进行相应操作...,因此得到问题的解,那么从根节点到当前节点对应的数值就是所兑换的硬币数值。...同时需要注意的是,并发每个节点都能再延伸出下层节点,例如第二层的节点4因为不能再使用面值为5的硬币兑换,因此它不能产生对应分支。

    49820

    本周小结!(动态规划系列五)

    组合总和 Ⅳ中给定一个由正整数组成且不存在重复数字的数组,找出和为给定目标正整数的组合的个数(顺序不同的序列被视作不同的组合)。...递归公式:dp[i] += dp[i - nums[j]]; 这个和前上周讲的组合问题又不一样,关键就体现在遍历顺序上! 在动态规划:518.零钱兑换II 中就已经讲过了。...此时大家应该发现这就是一个完全背包问题了! 和昨天的题目动态规划:377. 组合总和 Ⅳ基本就是一道题了,遍历顺序也是一样一样的!...周三 动态规划:322.零钱兑换给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数(每种硬币的数量是无限的)。...零钱兑换、动态规划:279.完全平方数 此时我们就已经把完全背包的遍历顺序研究的透透的了!

    63320

    零钱兑换 II-----完全背包套路模板

    ---- 零钱兑换 II 题解集合 完全背包(朴素解法) 完全背包(一维优化) 注意双重for循环的顺序 动态规划注意事项总结 记忆化搜索解法 ---- 完全背包(朴素解法) 在leetcode 322...零钱兑换中,我们求的是「取得特定价值所需要的最小物品个数」。 对于本题,我们求的是「取得特定价值的方案数量」。 求的东西不一样,但问题的本质没有发生改变,同样属于「组合优化」问题。...因为后者更为常用,所以我们再来回顾一下如何进行 换元一维优化 : 在二维解法的基础上,直接取消「物品维度」 确保「容量维度」的遍历顺序为「从小到大」(适用于「完全背包」) 将形如 dp[i][j-k*val...---- 记忆化搜索解法 递归的结束条件:凑出了目标钱数,找到了一种方案,返回1 , 或者枚举完了所有硬币,即越界了,说明当前没有可行方案,返回0 递归返回值:返回当前方案数 本级递归做什么:遍历硬币数组...可能存在的方案数进行累加求和 注意暴力递归会超时,这里还需要用依赖哈希表来存储已经求出来的结果,防止重复计算 其实如果用递归解,最好的方法还是把问题转化为多叉树的遍历,比较容易理解 那么重复计算是从哪里来的呢

    37740

    数据结构与算法入门手册

    图片 第一部分:算法概述 算法定义:一系列解决问题的清晰易行的步骤和规则。以编程实现,输入为问题实例,输出为问题解。 算法特征:输入、输出、有穷性、确定性、可行性。...算法类族:递归算法、迭代算法、确定算法、非确定算法、Exact算法、Heuristic算法等。递归算法通过递归解决子问题,迭代通过循环;确定算法对每组输入都给出同样的输出,非确定算法输出随输入变化。...第二部分:常用算法类型 图片 递归算法:子问题的解决依赖于递归算法,典型例子阶乘函数、斐波那契数列。需设置终止条件,否则会出现栈溢出。 贪心算法:在当前选项中做最佳选择,典型例子硬币找零、最小生成树。...递归算法:通过递归解决子问题,典型例子阶乘函数、斐波那契数列。需设置终止条件,否则栈溢出。...硬币找零:每次取面值最大的硬币,直到零钱数为0。 Prim算法:每次选取与当前树相连的权值最小的边,直到所有点被选取。 分治算法:通过递归将问题划分为相同或相似子问题,典型例子二分查找、快速排序。

    55940

    【动态规划背包问题】强化「换元一维优化」技巧

    前言 今天是我们讲解「动态规划专题」中的 「背包问题」的第七天。 本篇我们继续完成与 完全背包 相关的练习题,共三篇。 本篇是第三篇,第一篇在 这里,第二篇在 这里。...另外,我在文章结尾处列举了我所整理的关于背包问题的相关题目。 背包问题我会按照编排好的顺序进行讲解(每隔几天更新一篇,确保大家消化)。...你也先可以尝试做做,也欢迎你向我留言补充,你觉得与背包相关的 DP 类型题目 ~ 题目描述 这是 LeetCode 上的「518. 零钱兑换 II」,难度为 Medium。...给定不同面额的硬币和一个总金额。 写出函数来计算可以凑成总金额的硬币组合数。 假设每一种面额的硬币有无限个。...零钱兑换 中,我们求的是「取得特定价值所需要的最小物品个数」。 对于本题,我们求的是「取得特定价值的方案数量」。 求的东西不一样,但问题的本质没有发生改变,同样属于「组合优化」问题。

    1.1K62

    LeetCode-322-零钱兑换

    # LeetCode-322-零钱兑换 给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。...,xi是面值为ci的硬币数量,由于xi*ci不能超过S,可以得出xi的取值范围[0,S/xi] 一个简单的解决方案是枚举每个硬币数量子集[x0,......如果满足上述约束条件,计算硬币数量总和并返回所有子集中的最小值 for循环每一个硬币,选择0个1面值硬币,判断当前选择情况*面值是否小于等于总面值S,进入下层递归选择硬币应该固定1面值,选择2面值,idxCoin...,cn-1]:可选的n枚硬币面额值 这个问题有一个最优的子结构性质,这是解决动态规划问题的关键。最优解可以从其子问题的最优解构造出来。如何将问题分解成子问题?...下列递推关系成立: 在上面的递归树中,可以发现有许多子问题被多次计算。例如,F(1)被计算了13次。

    54720

    LeetCode-322-零钱兑换

    # LeetCode-322-零钱兑换 给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。...,xi是面值为ci的硬币数量,由于xi*ci不能超过S,可以得出xi的取值范围[0,S/xi] 一个简单的解决方案是枚举每个硬币数量子集[x0,......如果满足上述约束条件,计算硬币数量总和并返回所有子集中的最小值 for循环每一个硬币,选择0个1面值硬币,判断当前选择情况*面值是否小于等于总面值S,进入下层递归选择硬币应该固定1面值,选择2面值,idxCoin...,cn-1]:可选的n枚硬币面额值 这个问题有一个最优的子结构性质,这是解决动态规划问题的关键。最优解可以从其子问题的最优解构造出来。如何将问题分解成子问题?...下列递推关系成立: 在上面的递归树中,可以发现有许多子问题被多次计算。例如,F(1)被计算了13次。

    51410

    动态规划详解(修订版)

    显然二叉树节点总数为指数级别,所以子问题个数为 O(2^n)。 解决一个子问题的时间,在本算法中,没有循环,只有 f(n - 1) + f(n - 2) 一个加法操作,时间为 O(1)。...解决一个子问题的时间,同上,没有什么循环,时间为 O(1)。 所以,本算法的时间复杂度是 O(n)。比起暴力算法,是降维打击。 至此,带备忘录的递归解法的效率已经和迭代的动态规划一样了。...比如你想求amount = 11时的最少硬币数(原问题),如果你知道凑出amount = 10的最少硬币数(子问题),你只需要把子问题的答案加一(再选一枚面值为 1 的硬币)就是原问题的答案,因为硬币的数量是没有限制的...然后确定dp函数的定义:函数 dp(n)表示,当前的目标金额是n,至少需要dp(n)个硬币凑出该金额。 然后确定「选择」并择优,也就是对于每个状态,可以做出什么选择改变当前状态。...3、dp 数组的迭代解法 当然,我们也可以自底向上使用 dp table 来消除重叠子问题,dp数组的定义和刚才dp函数类似,定义也是一样的: dp[i] = x表示,当目标金额为i时,至少需要x枚硬币

    59550

    期望最大化(Expectation Maximization)算法简介和Python代码实现(附代码)

    它是一种迭代算法,可以将一个困难的优化问题分解为几个简单的优化问题。在本文中将通过几个简单的示例解释它是如何工作的。...对 p_1 取对数似然函数的导数,将其设置为零并求解 p_1。当区分对数似然函数时,涉及 p_2 的项的导数将等于 0。所以我们只使用涉及硬币 1 的实验数据。...在 EM 算法中,我们对这些概率进行初步猜测,然后在两个步骤之间迭代(估计偏差给定使用每个硬币的概率和估计使用每个硬币给定偏差的概率)直到收敛。...让我们将隐藏变量 Z 包含在似然函数中以获得完全似然: 完全似然函数的对数为: 这样就没有对数内的求和,更容易解决这个函数的最大化问题。...现在让我们试着让问题变得更复杂一些。假设选择每个硬币的概率是未知的。那么我们将有两个二项式的混合,选择第一个硬币的概率为 tau,选择第二个硬币的概率为 1-tau。 我们重复与之前相同的步骤。

    74630

    动态规划: 给我个机会,我再兑换一次零钱

    star支持一下吧 在动态规划:518.零钱兑换II中我们已经兑换一次零钱了,这次又要兑换,套路不一样!...编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。 你可以认为每种硬币的数量是无限的。...,可以看出是典型的完全背包问题。...在动态规划专题我们讲过了求组合数是动态规划:518.零钱兑换II,求排列数是动态规划:377. 组合总和 Ⅳ。...这也是我为什么要先讲518.零钱兑换II 然后再讲本题即:322.零钱兑换,这是Carl的良苦用心那。 相信大家看完之后,对背包问题中的遍历顺序又了更深的理解了。

    49310

    用javascript分类刷leetcode3.动态规划(图文视频讲解)

    什么是动态规划动态规划,英文:Dynamic Programming,简称DP,将问题分解为互相重叠的子问题,通过反复求解子问题来解决原问题就是动态规划,如果某一问题有很多重叠子问题,使用动态规划来解是比较有效的...动态规划和递归的区别:递归和回溯可能存在非常多的重复计算,动态规划可以用递归加记忆化的方式减少不必要的重复计算动态规划的解题方法递归+记忆化(自顶向下)动态规划(自底向上)图片解动态规划题目的步骤根据重叠子问题定义状态寻找最优子结构推导状态转移方程确定...零钱兑换 (medium)视频讲解:传送门给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。计算并返回可以凑成总金额所需的 最少的硬币个数 。...7,在用2个1,4 * 7 + 2 * 1 = 30,但是我们用5个6,5 * 6 = 30 就能用最少的硬币兑换完成方法1.动态规划思路:dp[i]表示兑换面额i所需要的最少硬币,因为硬币无限,所以可以自底向上计算...dp[i],对于dp[0~i]的每个状态,循环coins数组,寻找可以兑换的组合,用i面额减去当前硬币价值,dp[i-coin]在加上一个硬币数就是dp[i],最后取最小值就是答案,状态转移方程就是dp

    26410

    期望最大化(Expectation Maximization)算法简介和Python代码实现

    期望最大化(EM)算法被广泛用于估计不同统计模型的参数。它是一种迭代算法,可以将一个困难的优化问题分解为几个简单的优化问题。在本文中将通过几个简单的示例解释它是如何工作的。...对 p_1 取对数似然函数的导数,将其设置为零并求解 p_1。当区分对数似然函数时,涉及 p_2 的项的导数将等于 0。所以我们只使用涉及硬币 1 的实验数据。...在 EM 算法中,我们对这些概率进行初步猜测,然后在两个步骤之间迭代(估计偏差给定使用每个硬币的概率和估计使用每个硬币给定偏差的概率)直到收敛。...让我们将隐藏变量 Z 包含在似然函数中以获得完全似然: 完全似然函数的对数为: 这样就没有对数内的求和,更容易解决这个函数的最大化问题。...现在让我们试着让问题变得更复杂一些。假设选择每个硬币的概率是未知的。那么我们将有两个二项式的混合,选择第一个硬币的概率为 tau,选择第二个硬币的概率为 1-tau。 我们重复与之前相同的步骤。

    75530

    ​LeetCode刷题实战322:零钱兑换

    今天和大家聊的问题叫做 零钱兑换,我们先来看题面: https://leetcode-cn.com/problems/coin-change/ You are given an integer array...给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。你可以认为每种硬币的数量是无限的。...: 输入:coins = [1], amount = 2 输出:2 解题 https://blog.csdn.net/qq_23128065/article/details/104729144 背包问题的思路...,然后加上当前这一枚硬币,就是amount为index时所需的硬币个数,取这两种可能中的最小值就是所需最少硬币个数。...最后的ans[amount]中存储的就是兑换amount所需的硬币个数。

    28440
    领券