简体   繁体   English

打印所有验证括号,这里的递归工作如何?

[英]print all validate parentheses, how does the recursive work here?

Implement an algorithm to print all valid (eg, properly opened and closed) combinations of n-pairs of parentheses. 实现算法以打印n对括号的所有有效(例如,正确打开和关闭)组合。 EXAMPLE: input: 3 (eg, 3 pairs of parentheses) output: ()()(), ()(()), (())(), ((())) 示例:输入:3(例如,3对括号)输出:()()(),()(()),(())(),((()))

the answer is : 答案是 :

private static void printPar(int count)
{
    char[] str = new char[count*2];
    printPar(count,count,str, 0);
}

private static void printPar(int l, int r, char[] str, int count)
{
    if(l < 0 || r < l)
        return;

    if (l ==0 && r == 0)
    {
        System.out.println(str);
    }
    else
    {
        if (l > 0 )
        {
            str[count] = '(';
            printPar(l-1, r, str, count + 1);
        }

        if (r > 0)
        {
            str[count] = ')';
            printPar(l, r-1, str, count + 1);
        }
    }
}

But i dont quite fully understand the solution although someone claims the explanation is straightforward enough. 但我并不完全理解这个解决方案,尽管有人声称解释很简单。 (this code works fine) (此代码工作正常)

In my opinion, this code works as when there is more left parentheses, then add the left parentheses. 在我看来,这个代码的工作原理是左括号更多,然后添加左括号。 so, only condition of ((())) coz the condition if (l > 0 ) appear before r > 0 , so, it should always handle all the left ones first. 因此,只有((())的条件才能使条件如果(l> 0)出现在r> 0之前,那么,它应该始终首先处理所有左边的条件。

But how this code handle this situation "()(())"? 但是这段代码如何处理这种情况“()(())”? i debug this code, and find out that after it prints out "((()))". 我调试这段代码,并在打印出“((()))”之后发现它。 it went to the situation of l =1, r =3, and str="((()))" and count = 2. which doesnt make sense to me. 它进入了l = 1,r = 3和str =“((()))”和count = 2的情况。这对我来说没有意义。

Also, if someone can explain what is the time/space complexity, that would be much helpful for me. 此外,如果有人能够解释什么是时间/空间复杂性,那对我来说会很有帮助。

Thanks in advance. 提前致谢。

I drew a tree to show how the brackets are getting written for count = 3 . 我画了一棵树来展示如何为count = 3编写括号。 Each node represents a function call, with its text being a ( or ) , depending on what the calling function added. 每个节点代表一个函数调用,其文本为() ,具体取决于调用函数的添加内容。 The leaves are the calls where it gets printed. 叶子是打印的调用。

Since the depth of this tree is (obviously) at most 2.count , the space complexity is O(count) . 由于该树的深度(显然)最多为2.count ,因此空间复杂度为O(count)

Since every function call can either add a ( or a ) , the time complexity is at most O(2 number of function calls ) = O(2 2 count ) . 由于每个函数调用都可以添加(或a ) ,因此时间复杂度最多为O(2 number of function calls ) = O(2 2 count )

But, since the calls are conditional, the time complexity ends up being less, more specifically, it appears to be around O(2 2 count /count) , though I'm yet to prove that. 但是,由于调用是有条件的,时间复杂度最终会减少,更具体地说,它似乎在O(2 2 count /count) ,尽管我还没有证明这一点。

The code runs successfully because it doesn't let r < l. 代码运行成功,因为它不会让r <l。 If that is so, then it just discards the combination and returns. 如果是这样,那么它只是丢弃组合并返回。 That means a right bracket can come only after a left bracket. 这意味着右支架只能在左支架后出现。

The order of complexity, if you count the discarded recursive calls as well is (2n)!/( n! * n! ) . 复杂的顺序,如果你计算丢弃的递归调用也是(2n)!/( n! * n! ) This is the number of permutations of n '(' and n ')'. 这是n'('和n')'的排列数。

If you try to trace the code, it would run like follows: 如果您尝试跟踪代码,它将运行如下:

(
 (
  (
   )
    )
     ) 
      ((()))
  )
   (
    )
     )
      (()())
   )
    (
     )
      (())()
 )
  (
   (
    )
     )
      ()(())
(
 )
  (
   )
    (
     )
      ()()()

While recursing, the algorithm keeps track of the number of remaining left parentheses (l), the number of remaining right parenthesis (r), the result so far (str), and the number of parentheses generated (count). 在递归时,算法跟踪剩余左括号(l)的数量,剩余右括号(r)的数量,到目前为止的结果(str)以及生成的括号数(count)。

If no parentheses remains, a result is printed. 如果没有括号,则打印结果。

If at least one left parenthesis remains, it is used, and the function recurses to generate all results starting with the current prefix 如果剩下至少一个左括号,则使用它,并且函数会递归以生成以当前前缀开头的所有结果

Then, if at least one right parenthesis remains, and at least one left parenthesis is not closed, a right parenthesis it used, and the function recurses. 然后,如果至少有一个右括号,并且至少有一个左括号没有关闭,则使用右括号,并且函数会递归。

But how this code handle this situation "()(())"? 但是这段代码如何处理这种情况“()(())”? i debug this code, and find out that after it prints out "((()))". 我调试这段代码,并在打印出“((()))”之后发现它。 it went to the situation of l =1, r =3, and str="((()))" and count = 2. which doesnt make sense to me. 它进入了l = 1,r = 3和str =“((()))”和count = 2的情况。这对我来说没有意义。

When after printing ((())) the function is called with the parameters 1 , 3 , ((())) , and 2 , count=2 indicates that the only valid part of str is (( . Then, it continues adding a ) before recursing with the parameters 1 , 2 , (() , and 3 , resulting in (()()) being the next combination printed, followed by ()(()) , and ()()() . 当印刷之后((()))的函数被调用的参数13((()))2count=2表示的唯一有效的部分str((然后,继续添加一个)与所述参数递归前12(()3 ,得到(()())被印刷的下一组合,随后()(())()()()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM