[英]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.