Java 递归回溯makeChange
写一个方法makeChange,它使用递归回溯来找到所有方法来改变给定金额的货币,使用便士(1美分)、镍币(5美分)、一角硬币(10美分)和四分之一硬币(25美分) 例如,当兑换37美分时,您可以使用:Java 递归回溯makeChange,java,backtracking,recursive-backtracking,Java,Backtracking,Recursive Backtracking,写一个方法makeChange,它使用递归回溯来找到所有方法来改变给定金额的货币,使用便士(1美分)、镍币(5美分)、一角硬币(10美分)和四分之一硬币(25美分) 例如,当兑换37美分时,您可以使用: 四分之一 一角硬币和两便士 三角七分 或其他组合 您的方法应该接受一个参数:要进行更改的美分数 您的方法的输出应该是每种类型硬币的所有组合的序列,每行一个,加起来就是这个数量 例如,如果客户端代码包含以下调用: System.out.println(" P N D Q"); Syste
- 四分之一
- 一角硬币和两便士
- 三角七分
- 或其他组合
System.out.println(" P N D Q");
System.out.println("------------");
makeChange(28);
生成的总输出应如下所示:
P N D Q
------------ [3, 0, 0, 1] [3, 1, 2, 0] [3, 3, 1, 0] [3, 5, 0, 0] [8, 0, 2, 0] [8, 2, 1, 0] [8, 4, 0, 0] [13, 1, 1, 0] [13, 3, 0, 0] [18, 0, 1, 0] [18, 2, 0, 0] [23, 1, 0, 0] [28, 0, 0, 0]
解决这一问题的一个关键洞察是查看每种面值的硬币(便士、镍等),并尝试该硬币的所有可能数字(1便士、2便士、…、28便士),以查看从该选择开始可以进行哪些组合。例如,在上面的输出中,首先显示以3便士开始的所有组合,然后显示以8便士开始的所有组合,依此类推
由于回溯涉及到探索一组选项,因此您应该在代码中以某种方式表示硬币面额。我们建议保留一份所有硬币面值的清单,以便处理。在处理各种硬币价值时,可以修改此列表的内容。下面的模板是一个起点(您可以将其复制/粘贴到代码文本框中开始):
您可以假设传递给方法的更改量是非负的,但可能超过100
这是我的代码:
public static void makeChange(int amount){
int[] acc = new int[4];
makeChange(amount, acc);
}
private static void makeChange(int amount, int[] acc){
if(amount == 0){
System.out.print("[" + acc[0]);
for(int i = 1; i < 4; i++){
System.out.print(", " + acc[i]);
}
System.out.print("]");
System.out.println();
}
if(amount > 0){
acc[0]++;
makeChange(amount - 1, acc);
acc[0]--;
acc[1]++;
makeChange(amount - 5, acc);
acc[1]--;
acc[2]++;
makeChange(amount - 10, acc);
acc[2]--;
acc[3]++;
makeChange(amount - 25, acc);
acc[3]--;
}
}
…(有数百行输出)
有人能告诉我为什么会产生重复输出吗?
非常感谢 简单地说,你通过不同的途径得到了相同的解决方案。现在,代码的编写方式顺序很重要 简单易懂的案例: 假设我们要找6英镑的零钱。现在
1+5=5+1
所以在溶液中有[1,1,0,0]两次
方法1:先减去1,然后再减去5,最后得到0
方法2:先减去5,然后减去1,最后得到0
要仅获取唯一的解决方案,请使用HashSet
或TreeSet
将解决方案存储为ArrayList
(但不是数组),而不是在基本条件下打印。将最后的所有解决方案一起打印
另一种方法是,您可以添加第三个参数,指示您上次使用的硬币。您将使用面额为
=
的硬币作为最后一次使用的硬币。这确保了解决方案的独特性。简单地说,您通过不同的途径获得了相同的解决方案。现在,代码的编写方式顺序很重要
简单易懂的案例:
假设我们要找6英镑的零钱。现在1+5=5+1
所以在溶液中有[1,1,0,0]两次
方法1:先减去1,然后再减去5,最后得到0
方法2:先减去5,然后减去1,最后得到0
要仅获取唯一的解决方案,请使用HashSet
或TreeSet
将解决方案存储为ArrayList
(但不是数组),而不是在基本条件下打印。将最后的所有解决方案一起打印
另一种方法是,您可以添加第三个参数,指示您上次使用的硬币。您将使用面额为
=
的硬币作为最后一次使用的硬币。这确保了解决方案的唯一性。您是否在调试器中单步执行了代码?你发现了什么?看,我的电脑有个奇怪的问题,它无法在早上调试…所以我只能在脑子里运行代码。你在调试器中逐步调试了你的代码吗?你发现了什么?看,我的电脑有一个奇怪的问题,现在无法调试…所以我只能在脑子里运行代码。
public static void makeChange(int amount){
int[] acc = new int[4];
makeChange(amount, acc);
}
private static void makeChange(int amount, int[] acc){
if(amount == 0){
System.out.print("[" + acc[0]);
for(int i = 1; i < 4; i++){
System.out.print(", " + acc[i]);
}
System.out.print("]");
System.out.println();
}
if(amount > 0){
acc[0]++;
makeChange(amount - 1, acc);
acc[0]--;
acc[1]++;
makeChange(amount - 5, acc);
acc[1]--;
acc[2]++;
makeChange(amount - 10, acc);
acc[2]--;
acc[3]++;
makeChange(amount - 25, acc);
acc[3]--;
}
}
[28, 0, 0, 0]
[23, 1, 0, 0]
[23, 1, 0, 0]
[23, 1, 0, 0]
[23, 1, 0, 0]
[23, 1, 0, 0]
[23, 1, 0, 0]
[18, 2, 0, 0]
[18, 0, 1, 0]
[23, 1, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 0, 1, 0]
[23, 1, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 0, 1, 0]
[23, 1, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 0, 1, 0]
[23, 1, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 0, 1, 0]
[23, 1, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[13, 3, 0, 0]
[13, 1, 1, 0]
[18, 0, 1, 0]
[13, 1, 1, 0]
[23, 1, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[13, 3, 0, 0]
[13, 1, 1, 0]
[18, 2, 0, 0]
[13, 3, 0, 0]
[13, 3, 0, 0]
[13, 1, 1, 0]
[18, 0, 1, 0]
[13, 1, 1, 0]
[13, 1, 1, 0]
[23, 1, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[13, 3, 0, 0]
[13, 1, 1, 0]
[18, 2, 0, 0]
[13, 3, 0, 0]
[13, 3, 0, 0]
[13, 1, 1, 0]
[18, 2, 0, 0]
[13, 3, 0, 0]
[13, 3, 0, 0]
[13, 3, 0, 0]
[13, 1, 1, 0]
[18, 0, 1, 0]
[13, 1, 1, 0]
[13, 1, 1, 0]
[13, 1, 1, 0]
[23, 1, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[13, 3, 0, 0]
[13, 1, 1, 0]
[18, 2, 0, 0]
[13, 3, 0, 0]
[13, 3, 0, 0]
[13, 1, 1, 0]
[18, 2, 0, 0]
[13, 3, 0, 0]
[13, 3, 0, 0]
[13, 3, 0, 0]
[13, 1, 1, 0]
[18, 2, 0, 0]
[13, 3, 0, 0]
[13, 3, 0, 0]
[13, 3, 0, 0]
[13, 3, 0, 0]
[13, 1, 1, 0]
[18, 0, 1, 0]
[13, 1, 1, 0]
[13, 1, 1, 0]
[13, 1, 1, 0]
[13, 1, 1, 0]
[23, 1, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[18, 2, 0, 0]
[13, 3, 0, 0]
[13, 1, 1, 0]
[18, 2, 0, 0]
[13, 3, 0, 0]
[13, 3, 0, 0]
[13, 1, 1, 0]
[18, 2, 0, 0]
[13, 3, 0, 0]
[13, 3, 0, 0]
[13, 3, 0, 0]
[13, 1, 1, 0]