Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 理解硬币变化递归_Java_Recursion_Coin Change - Fatal编程技术网

Java 理解硬币变化递归

Java 理解硬币变化递归,java,recursion,coin-change,Java,Recursion,Coin Change,我试图用递归来解决硬币兑换问题,遇到了下面的代码 问题:给定一些面额的无限硬币,计算它们形成给定数量硬币的方式数 输入: int[] coins = {1, 2}; int amount = 5; int ways = change(amount, coins, coins.length - 1); // expected ways = 3 --> 11111, 1112, 122 代码: 我理解代码本身,也理解基本情况,但我无法理解它是如何封装递归/解决方案的 如果我在解factor

我试图用递归来解决硬币兑换问题,遇到了下面的代码

问题:给定一些面额的无限硬币,计算它们形成给定数量硬币的方式数

输入:

int[] coins = {1, 2}; 
int amount = 5;
int ways = change(amount, coins, coins.length - 1);
// expected ways = 3 --> 11111, 1112, 122
代码:

我理解代码本身,也理解基本情况,但我无法理解它是如何封装递归/解决方案的


如果我在解factorialn,我可以说factorialn=n*factorialn-1,所以我可以清楚地看到递归。在换硬币的例子中,我无法推断出类似的关系。有人能帮我吗?

递归行在这里:ways+=changeamount-coins[index],coins,index

我对代码做了一些注释来解释它

//金额是我们希望所有硬币加起来的总价值 //硬币上有我们可以加起来得到的价值 //索引是我们现在讨论的问题——我们将在稍后对此进行详细解释 整数兑换整数金额,整数[]硬币,整数索引{ //我们走得太低:最后一枚硬币太大,把我们推到了底片上 如果金额<0,则返回0; //找零!我们找到了用这些硬币找零的新方法 如果金额==0,则返回1; //数一数我们可以做出改变的方法 int-ways=0; //递归从这里开始:我们从索引开始,索引是 //我们可以得到硬币。在这种情况下,我们将一直走到世界的尽头 //数组到2硬币。我们将重复从数量中减去2,直到 //我们达到了0,这意味着我们只需要2枚硬币就可以达到这个数量,或者 //我们不能再往前走了。 //如果我们无法进一步,我们将从递归返回一级, //将指数减少1:这意味着我们现在正在尝试1硬币。 //这个过程会重复,尽可能多地使用2枚硬币进行更改 //当我们陷入困境或到达底部时,回到1硬币 //递归。 当金额>0&&index>=0时{ //反复尝试使用相同的硬币,当函数返回时, //无论是成功还是失败。。。 方式+=变更金额-硬币[指数],硬币,指数; //…移动到下一个硬币并重复此过程。 指数=指数-1; } //我们能够用这些硬币进行精确兑换的总次数 返回方式; } 更明确地说:

desired value: 5    available coins: 1, 2
value = 5
coin = 2
5 - 2 = 3

. value = 3
. coin = 2
. 3 - 2 = 1

. . value = 1
. . coin = 2
. . 1 - 2 = -1 | fail
. . coin = 1
. . 1 - 1 = 0 | success
. . no more coins to try

. value = 3
. coin = 1
. 3 - 1 = 2

. . value = 2
. . coin = 1
. . 2 - 1 = 1

. . . value = 1
. . . coin = 1
. . . 1 - 1 = 0 | success
. . . no more coins to try

. . no more coins to try

. no more coins to try

value = 5
coin = 1
5 - 1 = 4

. value = 4
[...and so on]

这里的递归行是:ways+=changeamount-coins[index],coins,index

我对代码做了一些注释来解释它

//金额是我们希望所有硬币加起来的总价值 //硬币上有我们可以加起来得到的价值 //索引是我们现在讨论的问题——我们将在稍后对此进行详细解释 整数兑换整数金额,整数[]硬币,整数索引{ //我们走得太低:最后一枚硬币太大,把我们推到了底片上 如果金额<0,则返回0; //找零!我们找到了用这些硬币找零的新方法 如果金额==0,则返回1; //数一数我们可以做出改变的方法 int-ways=0; //递归从这里开始:我们从索引开始,索引是 //我们可以得到硬币。在这种情况下,我们将一直走到世界的尽头 //数组到2硬币。我们将重复从数量中减去2,直到 //我们达到了0,这意味着我们只需要2枚硬币就可以达到这个数量,或者 //我们不能再往前走了。 //如果我们无法进一步,我们将从递归返回一级, //将指数减少1:这意味着我们现在正在尝试1硬币。 //这个过程会重复,尽可能多地使用2枚硬币进行更改 //当我们陷入困境或到达底部时,回到1硬币 //递归。 当金额>0&&index>=0时{ //反复尝试使用相同的硬币,当函数返回时, //无论是成功还是失败。。。 方式+=变更金额-硬币[指数],硬币,指数; //…移动到下一个硬币并重复此过程。 指数=指数-1; } //我们能够用这些硬币进行精确兑换的总次数 返回方式; } 更明确地说:

desired value: 5    available coins: 1, 2
value = 5
coin = 2
5 - 2 = 3

. value = 3
. coin = 2
. 3 - 2 = 1

. . value = 1
. . coin = 2
. . 1 - 2 = -1 | fail
. . coin = 1
. . 1 - 1 = 0 | success
. . no more coins to try

. value = 3
. coin = 1
. 3 - 1 = 2

. . value = 2
. . coin = 1
. . 2 - 1 = 1

. . . value = 1
. . . coin = 1
. . . 1 - 1 = 0 | success
. . . no more coins to try

. . no more coins to try

. no more coins to try

value = 5
coin = 1
5 - 1 = 4

. value = 4
[...and so on]

计算制造50个货币单位的方法的一部分是说,如果我使用10个单位的硬币,那么剩下的40个单位我就不得不制造了:这是多少种方法?。这就是递归关系。这就是我想要得到的!你能详细说明一下吗?如果我想从{2,1}得到5,我需要在从{2,1}得到3的解中添加什么?基本上,在阶乘递归中,我必须将n乘以上一个解。这里对应的概念是什么?要从2和1生成5,你可以从2开始,然后有很多方法生成剩余的3;或者你可以从1开始,然后有很多方法来制作剩下的4。这两个选项组合在一起

n给你一些制作的方法。谢谢!仍然不是100%清楚,但我会花一些时间在上面。计算制作方法的数量,比如说50个货币单位,部分是说如果我使用10个单位的硬币,那么剩下的40个单位我就不得不制作了:这是多少种方式?。这就是递归关系。这就是我想要得到的!你能详细说明一下吗?如果我想从{2,1}得到5,我需要在从{2,1}得到3的解中添加什么?基本上,在阶乘递归中,我必须将n乘以上一个解。这里对应的概念是什么?要从2和1生成5,你可以从2开始,然后有很多方法生成剩余的3;或者你可以从1开始,然后有很多方法来制作剩下的4。这两个选项的组合为您提供了许多制作5的方法。谢谢!仍然不是100%清楚,但我会花一些时间在上面。我感谢你花时间回答和写评论,我完全理解代码,但试着理解递归,即如何从以前的解决方案中得到当前解决方案。@用最简单的方法:拿一张纸和一支笔,并绘制代码的路径:每次返回时向前和向后。当你回到起点时,它会sense@Ufder我添加了一个直观的解释。@Ufder选择最大的硬币,并尽可能多地从总金额中减去它。如果遇到负数,请撤消最后一次减法,选择下一个最小的硬币,然后继续尝试。如果你达到0,这算成功-记录它,然后撤销减法,直到你得到你使用的前一枚硬币。将其更改为当前硬币,然后重复。这样做,直到你测试了每一枚硬币。请注意,为了便于解释,在本例中,硬币是按大小排序的,但你不需要对它们进行排序以使算法发挥作用。@NickReed Dude,所有那些youtube视频中,他们说“选择一枚硬币vs丢弃一枚硬币”,我无法理解,但一旦我看到你的评论,我马上就明白了。非常感谢。感谢您花时间回答和撰写注释,我完全理解代码,但我试图理解递归,即如何从以前的解决方案中获得当前解决方案。@U使用最简单的方法:用纸和笔,绘制代码路径:每次返回时向前和向后。当你回到起点时,它会sense@Ufder我添加了一个直观的解释。@Ufder选择最大的硬币,并尽可能多地从总金额中减去它。如果遇到负数,请撤消最后一次减法,选择下一个最小的硬币,然后继续尝试。如果你达到0,这算成功-记录它,然后撤销减法,直到你得到你使用的前一枚硬币。将其更改为当前硬币,然后重复。这样做,直到你测试了每一枚硬币。请注意,为了便于解释,在本例中,硬币是按大小排序的,但你不需要对它们进行排序以使算法发挥作用。@NickReed Dude,所有那些youtube视频中,他们说“选择一枚硬币vs丢弃一枚硬币”,我无法理解,但一旦我看到你的评论,我马上就明白了。非常感谢。