计算爬楼梯方式的递归解决方案

发布于 2025-01-11 11:24:26 字数 991 浏览 3 评论 0原文

我试图用递归解决“计算到达楼梯第 n 级台阶的方法”的问题。当给定多个要爬的楼梯时,我必须计算一次爬 1 步或 2 步的攀登方式的数量。例如,如果有 4 个楼梯,我们将返回 5,因为我们会:

  * 1 1 1 1
  * 1 1 2
  * 1 2 1
  * 2 1 1
  * 2 2

我的代码当前抛出堆栈溢出异常:

 public static int countWaysToClimb(int stairs) {
     return countWaysToClimbHelper(stairs, 0, 0);
 }
 
 public static int countWaysToClimbHelper(int sumNeeded, int currentSum, int possibleCombos) {
     // base - we will reach this base multiple times
     if (sumNeeded == currentSum) {
         possibleCombos++;
         // if we already found a combo, we need to reset the sum
         countWaysToClimbHelper(sumNeeded,0,possibleCombos);  
     }
     
     else if (currentSum > sumNeeded) {
         return 0;
     }
     
     // recurse - add 1 and then add 2
     countWaysToClimbHelper(sumNeeded,currentSum+1,possibleCombos);  
     countWaysToClimbHelper(sumNeeded,currentSum+2,possibleCombos);
     return possibleCombos;             
 }

谢谢!

I'm trying to solve the problem of "count ways to reach the nth step in a staircase" with recursion. When given a number of stairs to climb, I have to calculate the number of ways to climb taking either 1 or 2 steps at a time. For example, if there are 4 stairs, we would return 5 since we would have:

  * 1 1 1 1
  * 1 1 2
  * 1 2 1
  * 2 1 1
  * 2 2

My code is currently throwing a stack overflow exception:

 public static int countWaysToClimb(int stairs) {
     return countWaysToClimbHelper(stairs, 0, 0);
 }
 
 public static int countWaysToClimbHelper(int sumNeeded, int currentSum, int possibleCombos) {
     // base - we will reach this base multiple times
     if (sumNeeded == currentSum) {
         possibleCombos++;
         // if we already found a combo, we need to reset the sum
         countWaysToClimbHelper(sumNeeded,0,possibleCombos);  
     }
     
     else if (currentSum > sumNeeded) {
         return 0;
     }
     
     // recurse - add 1 and then add 2
     countWaysToClimbHelper(sumNeeded,currentSum+1,possibleCombos);  
     countWaysToClimbHelper(sumNeeded,currentSum+2,possibleCombos);
     return possibleCombos;             
 }

Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

辞慾 2025-01-18 11:24:26

您的代码中存在一些问题:

  • 基本情况(终止递归的条件)不正确。递归调用的每个分支在满足条件 if (sumNeeded == currentSum) is eat 时生成新分支,而不是返回组合数。您创建了无限递归,这不可避免地会导致 StackOverflowError。您必须在代码中第一个 if 之后的大括号内放置 return 语句。并注释掉第一个递归调用(将 0 sum 作为参数传递),您将面临第二个问题:对于任何输入,您的代码将产生 0
  • 方法 countWaysToClimbHelper()递归调用返回的结果将被忽略。变量 possibleCombos 不受这些调用的影响。每个方法调用都会在堆栈(JVM 为每个方法调用存储数据的内存区域)上分配该变量possibleCombos 的自己的副本,并且它们的值无论如何都不相关。
  • 实际上,您不需要将组合数量作为参数传递,而是需要返回它

在进一步讨论之前,让我回顾一下递归的基础知识。

每个递归方法都应包含两部分

  • 基本情况 - 表示提前知道结果的简单边缘情况。对于这个问题,有两种边缘情况:
    • sumNeeded == currentSum - 返回值为1,即找到一个组合;
    • 所需总和> currentSum - 返回值为0
  • 递归案例 - 解决方案的一部分,其中递归调用以及主逻辑所在。在您的递归情况中,您需要累积组合数量的值,这将是两个执行分支返回的值的总和:采取1步2步

因此,固定代码可能如下所示:

public static int countWaysToClimb(int stairs) {
    return countWaysToClimbHelper(stairs, 0);
}

public static int countWaysToClimbHelper(int sumNeeded, int currentSum) {
    // base - we will reach this base multiple times
    if (sumNeeded == currentSum) {
        return 1;
    } else if (currentSum > sumNeeded) {
        return 0;
    }
    // recurse - add 1 and then add 2
    int possibleCombos = 0;
    possibleCombos += countWaysToClimbHelper(sumNeeded,currentSum + 1);
    possibleCombos += countWaysToClimbHelper(sumNeeded,currentSum + 2);
    return possibleCombos;
}

注意:

  • 此代码可以进一步增强。整个逻辑可以在 countWaysToClimb() 内部实现,而无需使用辅助方法。为此,您需要在递归调用该方法时从 sumNeeded 中减去步数,而不是跟踪 currentSum

There are some issues in your code:

  • Base case (condition that terminates the recursion) is incorrect. Every branch of recursive calls spawn new branches when it hits the condition if (sumNeeded == currentSum) is meat instead of returning the number of combinations. You created an infinite recursion that inevitably leads to a StackOverflowError. You have to place a return statement inside the curly braces after the first if in your code. And comment out the first recursive call (with 0 sum passed as an argument) you'll face the second problem: for any input, your code will yield 0.
  • Results returned by recursive calls of your method countWaysToClimbHelper() are omitted. Variable possibleCombos isn't affected by these calls. Each method call allocates its own copy of this variable possibleCombos on the stack (a memory aria where JVM stores data for each method call), and their values are not related anyhow.
  • you actually don't need to pass the number of combinations as a parameter, instead you have to return it.

Before moving further, let me recap the basics of recursion.

Every recursive method should contain two parts:

  • base case - that represents a simple edge-case for which the outcome is known in advance. For this problem, there are two edge-cases:
    • sumNeeded == currentSum - the return value is 1, i.e. one combination was found;
    • sumNeeded > currentSum - the return value is 0.
  • recursive case - a part of a solution where recursive calls a made and when the main logic resides. In your recursive case you need to accumulate the value of the number of combination, which will be the sum of values returned be two branches of execution: take 1 step or 2 steps.

So the fixed code might look like that:

public static int countWaysToClimb(int stairs) {
    return countWaysToClimbHelper(stairs, 0);
}

public static int countWaysToClimbHelper(int sumNeeded, int currentSum) {
    // base - we will reach this base multiple times
    if (sumNeeded == currentSum) {
        return 1;
    } else if (currentSum > sumNeeded) {
        return 0;
    }
    // recurse - add 1 and then add 2
    int possibleCombos = 0;
    possibleCombos += countWaysToClimbHelper(sumNeeded,currentSum + 1);
    possibleCombos += countWaysToClimbHelper(sumNeeded,currentSum + 2);
    return possibleCombos;
}

Note:

  • This code could be enhanced further. The whole logic can be implemented inside the countWaysToClimb() without using a helper-method. For that, instead of tracking the currentSum you need to subtract the number of steps from the sumNeeded when the method is called recursively.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文