生成括号问题超出了Python递归深度

时间:2019-06-06 10:24:05

标签: python python-3.x

我正在按照以下方式使用蛮力解决Generate Parenthesis Problem

class Solution:
    def generateParenthesis(self, n: int) -> List[str]:
        C, ans = [], []
        ans = self.generate(C, n, ans)
        return ans

    def generate(self, C, n, ans):
        if len(C) == 2*n:
            if self.valid(C):
                ans.append(''.join(C))
        else:
            C.append('(')
            ans = self.generate(C, n, ans)
            C.pop()
            C.append(')')
            ans = self.generate(C, n, ans)
            C.pop()
        return ans


    def valid(self, C):
        bal = 0
        for c in C:
            if c == '(': bal+=1
            else: bal-=1
            if bal<0: return False
        return bal == 0

我遇到以下错误

RecursionError: maximum recursion depth exceeded in comparison
Line 8 in generate(solution.py)

当我按如下方式组合8、9和10行时,我再也看不到错误了。

if len(C) == 2*n and self.valid(C):
    ans.append(''.join(C))

似乎有点奇怪。为什么会这样?

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

代码更改后,您的程序在逻辑上不再等效于先前的实现。 查看else分支,您会明白我的意思。在原始版本中,如果满足以下条件,则执行else分支

len(C)!= 2 * n

在修改后的版本中,如果满足以下条件,则会执行

len(C)!= 2 * n或不为self.valid(C)

但是目前我不知道为什么这种变化可以解释观察到的行为,因为它甚至会产生更多的调用来生成。

顺便说一句。如果考虑到以下条件,则无需检查逻辑:()的所有组合都是有效的,只要在迭代过程中满足以下条件:

  • 在生成调用的每个级别上,关闭括号的数量最多等于打开括号的数量
  • 在生成调用的每个级别上,您最多具有n个左括号

有了这些知识,您可以使用:

class Solution2:
    def generateParenthesis(self, n: int) -> List[str]:
        C, ans = [], []
        ans = self.generate(C, n, ans, 0, 0)
        return ans

    def generate(self, C, n, ans, op, cl):
        #print(n, op, cl)
        if op < n or cl < n:
            if op < n:
                ans = self.generate(C + ['('], n, ans, op+1, cl)
            if op > cl:
                ans = self.generate(C + [')'], n, ans, op,   cl+1)
        else:
            ans.append(''.join(C))
        return ans

答案 1 :(得分:-1)

让n = 2

如果我们构造一个递归树,则长度为2*n=2*2=4的第一个字符串是C="(((("

现在C的长度为2*n,但无效

所以,条件 len(C) == 2*n and self.valid(C)False

现在将执行else部分,并且程序将运行到无限递归调用中。

PS:感谢@Jottbe指出逻辑错误