簡體   English   中英

計算 go 上樓梯的方式數的遞歸解決方案

[英]Recursive solution to counting the number of ways you can go up a staircase

我正在嘗試通過遞歸解決“計算到達樓梯第 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;             
 }

謝謝!

您的代碼中存在一些問題:

  • 基本情況(終止遞歸的條件)不正確 遞歸調用的每個分支在滿足條件if (sumNeeded == currentSum) is meat 時都會生成新分支,而不是返回組合數。 您創建了一個不可避免地導致StackOverflowError的無限遞歸。 您必須在代碼中第一個if之后的大括號內放置一個return語句。 並注釋掉第一個遞歸調用(將0 sum 作為參數傳遞)你將面臨第二個問題:對於任何輸入,你的代碼將產生0
  • 方法countWaysToClimbHelper()遞歸調用返回的結果將被忽略。 變量possibleCombos不受這些調用的影響。 每個方法調用都會在堆棧上分配此變量possibleCombos的副本(memory aria,其中 JVM 存儲每個方法調用的數據),並且它們的值無論如何都不相關。
  • 您實際上不需要將組合數作為參數傳遞,而是必須返回它

在進一步討論之前,讓我回顧一下遞歸的基礎知識。

每個遞歸方法都應該包含兩部分

  • 基本案例- 代表一個簡單的邊緣案例,其結果是預先知道的。 對於這個問題,有兩種邊緣情況:
    • sumNeeded == currentSum - 返回值為1 ,即找到一個組合;
    • sumNeeded > currentSum - 返回值為0
  • 遞歸案例- 解決方案的一部分,其中遞歸調用已完成並且主要邏輯所在。 在您的遞歸情況下,您需要累積組合數量的值,這將是兩個執行分支返回的值的總和: take 1 step2 steps

所以固定代碼可能看起來像這樣:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM