问题:
在此问题中,我们正在评估的方案如下:您站在楼梯的底部,并正在走向顶部。一小步将向上移动一个楼梯,一个大步将向前移动两个楼梯。您想根据大小步幅的不同组合来计算爬上整个楼梯的方法数量。例如,一个三级台阶的楼梯可以用三种不同的方式攀登:三个小步,一个小步子,然后一个大步子,或者一个大步子跟一个小步子。
对 waysToClimb(3( 的调用应该产生以下输出:
1 1 1,
1 2,
2 1
我的代码:
public static void waysToClimb(int n){
if(n == 0)
System.out.print("");
else if(n == 1)
System.out.print("1");
else {
System.out.print("1 ");
waysToClimb(n - 1);
System.out.print(",");
System.out.print("2 ");
waysToClimb(n - 2);
}
}
我的输出:
1 1 1,
2,
2 1
我的递归似乎不记得它所走的路径,不知道如何解决它?
编辑:
谢谢你们的回复。抱歉回复晚了
我想通了
public static void waysToClimb(int n){
String s ="[";
int p=0;
com(s,p,n);
}
public static void com(String s,int p,int n){
if(n==0 && p==2)
System.out.print(s.substring(0,s.length()-2)+"]");
else if(n==0 && p !=0)
System.out.print(s+"");
else if(n==0 && p==0)
System.out.print("");
else if(n==1)
System.out.print(s+"1]");
else {
com(s+"1, ",1,n-1);
System.out.println();
com(s+"2, ",2,n-2);
}
}
如果您明确想要打印所有路径(不同于计算它们或查找特定路径(,则需要将它们一直存储到 0。
public static void waysToClimb(int n, List<Integer> path)
{
if (n == 0)
{
// print whole path
for (Integer i: path)
{
System.out.print(i + " ");
}
System.out.println();
}
else if (n == 1)
{
List<Integer> newPath = new ArrayList<Integer>(path);
newPath.add(1);
waysToClimb(n-1, newPath);
}
else if (n > 1)
{
List<Integer> newPath1 = new ArrayList<Integer>(path);
newPath1.add(1);
waysToClimb(n-1, newPath1);
List<Integer> newPath2 = new ArrayList<Integer>(path);
newPath2.add(2);
waysToClimb(n-2, newPath2);
}
}
初始调用:waysToClimb(5, new ArrayList<Integer>());
提到的解决方案将类似于深度优先搜索,它将探索一条路径。路径完成后,它将回溯并探索其他路径:
public class Demo {
private static LinkedList<Integer> ll = new LinkedList<Integer>(){{ add(1);add(2);}};
public static void main(String args[]) {
waysToClimb(4, "");
}
public static void waysToClimb(int n, String res) {
if (ll.peek() > n)
System.out.println(res);
else {
for (Integer elem : ll) {
if(n-elem >= 0)
waysToClimb(n - elem, res + String.valueOf(elem) + " ");
}
}
}
}
public class Test2 {
public int climbStairs(int n) {
// List of lists to store all the combinations
List<List<Integer>> ans = new ArrayList<List<Integer>>();
// initially, sending in an empty list that will store the first combination
csHelper(n, new ArrayList<Integer>(), ans);
// a helper method to print list of lists
print2dList(ans);
return ans.size();
}
private void csHelper(int n, List<Integer> l, List<List<Integer>> ans) {
// if there are no more stairs to climb, add the current combination to ans list
if(n == 0) {
ans.add(new ArrayList<Integer>(l));
}
// a necessary check that prevent user at (n-1)th stair to climb using 2 stairs
if(n < 0) {
return;
}
int currStep = 0;
// i varies from 1 to 2 as we have 2 choices i.e. to either climb using 1 or 2 steps
for(int i = 1; i <= 2; i++) {
// climbing using step 1 when i = 1 and using 2 when i = 2
currStep += 1;
// adding current step to the arraylist(check parameter of this method)
l.add(currStep);
// make a recursive call with less number of stairs left to climb
csHelper(n - currStep, l, ans);
l.remove(l.size() - 1);
}
}
private void print2dList(List<List<Integer>> ans) {
for (int i = 0; i < ans.size(); i++) {
for (int j = 0; j < ans.get(i).size(); j++) {
System.out.print(ans.get(i).get(j) + " ");
}
System.out.println();
}
}
public static void main(String[] args) {
Test2 t = new Test2();
t.climbStairs(3);
}
}
请注意,对于较大的输入,此解决方案将超时,因为这不是记忆的递归解决方案,并且可能会抛出 MLE(因为我在找到组合时会创建一个新列表(。
希望这有帮助。
如果有人在寻找Python解决方案,这个问题。
def way_to_climb(n, path=None, val=None):
path = [] if path is None else path
val = [] if val is None else val
if n==0:
val.append(path)
elif n==1:
new_path = path.copy()
new_path.append(1)
way_to_climb(n-1, new_path, val)
elif n>1:
new_path1 = path.copy()
new_path1.append(1)
way_to_climb(n-1, new_path1, val)
new_path2 = path.copy()
new_path2.append(2)
way_to_climb(n-2, new_path2, val)
return val
注意:它基于@unlut解决方案,这里OP使用了自上而下的递归方法。此解决方案适用于所有在 python 中寻找楼梯问题组合的人,没有 python 问题,所以我在这里添加了一个 python 解决方案
如果我们使用自下而上的方法并使用记忆,那么我们可以更快地解决问题。
即使你确实找到了代码问题的正确答案,你仍然可以通过只使用一个 if 来检查剩下的步骤是否为 0 来改进它。我使用开关来检查所采取的步骤数,因为只有 3 个选项,0、1 或 2。我还重命名了用于使第一次看到代码的人更容易理解代码的变量,因为如果您只使用一个字母的变量名称,则会非常混乱。即使进行了所有这些更改,代码的运行也相同,我只是认为最好为将来可能查看此问题的其他人添加其中一些内容。
public static void climbStairsHelper(String pathStr, int stepsTaken, int stepsLeft)
{
if(stepsLeft == 0)
{
switch(stepsTaken)
{
case 2:
System.out.print(pathStr.substring(0, pathStr.length() - 2) + "]");
break;
case 1:
System.out.print(pathStr + "");
break;
case 0:
System.out.print("");
break;
}
}
else if(stepsLeft == 1)
{
System.out.print(pathStr + "1]");
}
else
{
climbStairsHelper(pathStr + "1, ", 1, stepsLeft - 1);
System.out.println();
climbStairsHelper(pathStr + "2, ", 2, stepsLeft - 2);
}
}`
'