【发布时间】:2019-06-09 15:22:13
【问题描述】:
示例
给定一个数组 [1,2,3] 或 [1,2,3,4] ,打印长度为 3 的所有唯一组合。
代码
public class PrintCombo {
public void printCombo(int [] a, int [] buffer, int startIndex, int bufferIndex){
printArray(buffer);
if(buffer.length == bufferIndex){
System.out.println();
System.out.println("SOLUTION START");
printArray(buffer);
System.out.println("SOLUTION END");
System.out.println();
return;
}
if(startIndex == a.length){
return;
}
for(int i = startIndex; i<a.length; i++){
buffer[bufferIndex] = a[i];
printCombo(a,buffer,i+1,bufferIndex+1);
}
}
public void printArray(int [] buffer){
for(int i = 0; i<buffer.length; i++){
System.out.print(" "+buffer[i]);
}
System.out.println();
}
}
输出
对于数组 [1,2,3] ==> 1,2,3
对于数组 [1,2,3,4] ==> 1,2,3 || 1,2,4 || 1,3,4 || 2,3,4
问题
我已经使用调试器跟踪代码 3 个小时,但我仍在努力理解递归逻辑是如何工作的。
例如,我们以数组为[1,2,3]为例。
- PrintCombo(a, buffer, 0, 0)
- buffer[0] 更新为 1
- 我们调用 PrintCombo(a, buffer, 1, 1)
- buffer[1] 更新为 2
- 我们调用 PrintCombo(a, buffer, 2, 2)
- buffer[2] 更新为 3
- 我们调用 PrintCombo(a, buffer, 3, 3)
- 由于 buffer.length == bufferIndex 我们称之为 printArray。
- 我们回到之前的调用
这是我迷路的地方。堆栈如何进行先前的调用?我正在努力彻底理解这种方法,因为我不喜欢记住解决方案。
我决定通过添加一个打印语句来编辑我的代码,以便在每次迭代时查看缓冲区内的内容。这是我打印的内容,例如 a = [1,2,3],缓冲区大小为 3。
0 0 0
1 0 0
1 2 0
1 2 3
SOLUTION START
1 2 3
SOLUTION END
1 3 3
2 3 3
2 3 3
3 3 3
【问题讨论】:
-
是否需要使用递归来解决这个问题?
-
@TimBiegeleisen 是的。我知道我们可以替代地解决它,但我真的为了我自己的利益而试图理解递归方法。
-
递归方法不经常使用,因为大多数循环更容易调试并且不太可能进入无限期,但它们通常是这样工作的: 1. 检查退出条件的保护语句。 2. 导致对同一方法的一次或多次调用的逻辑,其中更新的参数适用于保护语句中存在的一个或多个条件
-
@AustinSchäfer 是的,理论上我明白了,但我在追踪上述问题时遇到了特别的麻烦,如果你能帮助追踪它,我将不胜感激。
标签: java recursion combinations