簡體   English   中英

了解多個遞歸調用的用例

[英]Understanding the usecase of multiple recursive calls

我正在嘗試解決一個問題,以便在給定整數的情況下獲得所有可能的有效括號組合。 例如。 input: n = 2, output: (()), ()()

顯然,隨着n增加,當前輸出建立在前n個的輸出之上。 因此,通過獲取先前的結果並將其添加以獲得當前結果,很容易得出一個遞歸:

HashSet<String> getCombinations(int n)
{
    HashSet<String> result = new HashSet<String>();
    if (n <= 0) return null;
    if (n == 1)
    {
        result.add("()");
        return result;
    }
    for (String str: getCombinations(n - 1))
    {
        for (int i = 0; i < str.length(); i++)
        {
            result.add(new StringBuffer(str).insert(i, "()").toString());
        }
    }
    return result;
}

盡管顯然上述代碼的缺點是重復產生但未存儲的相同結果值。 因此,我在網上尋找了更好的解決方案(因為我無法想到),並發現了這一點:

ArrayList<String> result = new ArrayList<>();
void getCombinations(int index, int nLeft, int nRight, String str)
{
    if (nLeft < 0 || nRight < 0 || nLeft > nRight) return;
    if (nLeft == 0 && nRight == 0)
    {
        result.add(str);
        return;
    }
    getCombinations(index + 1, nLeft - 1, nRight, new StringBuffer(str).insert(index, "(").toString());
    getCombinations(index + 1, nLeft, nRight - 1, new StringBuffer(str).insert(index, ")").toString());
}

我了解此解決方案的工作原理,以及為什么它比第一個更好。 但是即使到現在,我也無法想象先解決第一個解決方案,然后提出第二個解決方案。 如何直觀地理解何時使用多個遞歸調用? 換句話說,在獲得解決方案1之后,我怎么能認為多次遞歸調用可能會更好呢?

我的問題不是上述問題特有的,而是一般問題的類型。

您可以將這個問題看做1和-1的排列,將它們相加在一起時,運行總和(溫度值,從左至右加總的溫度)不得小於0,或者在括號的情況下必須不要使用比左括號更多的右括號。 所以:

如果n=1 ,則只能執行1+(-1) 如果n=2 ,則可以做1+(-1)+1+(-1)1+1+(-1)+(-1)

因此,在創建這些排列時,您會看到在每個遞歸調用中只能使用兩個選項之一( 1-1 ,並且通過跟蹤nLeftnRight使用的nLeft ,可以使程序知道什么時候停止。

暫無
暫無

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

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