[英]Understanding binary-search-tree (BST) delete implementation with recursive calls
[英]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
,並且通過跟蹤nLeft
和nRight
使用的nLeft
,可以使程序知道什么時候停止。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.