这是一个非常经典的问题,我听说谷歌在采访中使用了这个问题。
问题:制作一个递归方法,打印从楼梯底部到n楼梯楼梯顶部的所有可能的独特方式。您一次只能采取一步或两步。
样品输出:如果它是一个有3个楼梯的楼梯......
1 1 1
2 1
1 2
如果是一个有4个楼梯的楼梯......
1 1 1 1
1 1 2
1 2 1
2 1 1
2 2
*输出顺序无关紧要
我在这里发布了类似的问题,但他们都询问了路径的总数。这种递归方法需要打印出所有可能的路径。 这里唯一的限制是你必须在方法的某个地方使用递归。如果需要,可以使用多种方法。
答案 0 :(得分:3)
好吧,如果你剩下0楼梯,你已经到了尽头;如果你还有一个楼梯,下一步只能是1;如果你前面有更多的楼梯,下一步可能是1或2级楼梯,所以递归变得非常简单:
void makeSteps(List<Integer> prevSteps, int s) {
if (s == 0) { // no more stairs left
System.out.println(prevSteps);
} else { // 1 or more stairs left
List<Integer> n1 = new ArrayList<>(prevSteps);
n1.add(1);
makeSteps(n1, s - 1);
if (s > 1) { // 2 or more stairs left
List<Integer> n2 = new ArrayList<>(prevSteps);
n2.add(2);
makeSteps(n2, s - 2);
}
}
}
prevSteps
代表上一条路径,s
存储剩余的楼梯数。要打印n步楼梯的所有可能方式,请致电:
makeSteps(new ArrayList<>(), n);
很容易将此代码重构为更通用的形式,其中步长不仅可以是1或2,而且可以是maxStep
以下的任何数字:
void makeSteps(List<Integer> prevSteps, int s, int maxStep) {
if (s == 0) { // no more stairs left
System.out.println(prevSteps);
} else { // 1 or more stairs left
for (int step = 1; step <= Math.min(maxStep, s); step++) {
List<Integer> newSteps = new ArrayList<>(prevSteps);
newSteps.add(step);
makeSteps(newSteps, s - step, maxStep);
}
}
}
要获得相同的结果,请使用第三个参数调用它:
makeSteps(new ArrayList<>(), 4, 2);