【问题标题】:Recursion Question with Valid Parenthesis带有效括号的递归问题
【发布时间】:2021-04-10 16:12:43
【问题描述】:

我正在尝试理解这个生成所有有效括号的解决方案。

我不明白的部分是递归如何找到所有不同的组合。当我调试代码时,我对整数“left”和“right”进行了观察。在 generateParenthesis 中输入 2 后,在“ans”填充有 1 个有效括号后,在“return ans”处,我看到变量“right”减少,使 if 语句“right

下面我将问题与在线 Python 调试器一起包含在内,以了解我在说什么。 https://onlinegdb.com/LMNYtq3iR

https://leetcode.com/problems/generate-parentheses/

def generateParenthesis(N):
   ans = []
   S = ''
   left = 0
   right = 0
   ans = backtrack(N, S, left, right, ans)

def backtrack(N, S, left, right, ans):
   print(left)
   if len(S) == 2 * N:
      ans.append(S)
   if left < N:
      backtrack(N, S+'(', left+1, right, ans)
   if right < left:
    backtrack(N, S+')', left, right+1, ans)

   return ans
    
generateParenthesis(2)

【问题讨论】:

    标签: python algorithm recursion backtracking


    【解决方案1】:

    变量 right 从不减少。您会看到早期递归执行的价值。如果您在输出中包含当前递归级别,可能会变得更清楚:

    print(" "*len(S), S, left, right)
    
      0 0
      ( 1 0
       (( 2 0
        (() 2 1
         (()) 2 2
       () 1 1   <-- left and right do not decrease, this is the call after `( 1 0` above
        ()( 2 1
         ()() 2 2
    

    在不相关的注释中,您在这里使用的 return 不一致。 backtrack 函数根本不需要return,因为它向ans 参数添加元素,而generateParenthesis 根本不返回。我建议删除 ans 参数并将函数更改为适当的生成器函数:

    def generateParenthesis(N):
       return backtrack(N, S="", left=0, right=0)
    
    def backtrack(N, S, left, right):
       print(" "*len(S), S, left, right)
       if len(S) == 2 * N:
           yield S
       if left < N:
           yield from backtrack(N, S+'(', left+1, right)
       if right < left:
           yield from backtrack(N, S+')', left, right+1)
        
    print(list(generateParenthesis(2)))
    

    【讨论】:

      【解决方案2】:

      这与框架在 Python 中的工作方式有关。在程序的执行过程中,我们基本上从调用具有来自 generateParanthesis 的值的变量调用 backtrack 开始,然后由于 left 小于 N,我们得到一个对 backtrack 的递归调用,left 被迭代,程序沿着这条线继续,在递归调用之后。所以你打开一堆新的帧,做一堆不同的操作,在程序到达下一行之前,发现那个帧中的左右相等,然后返回答案。您正在看到类似的事情发生;本质上,您进入后一帧,然后一旦该帧关闭,就返回到右较少的较早帧。权利从未减少,程序只是回到权利较少的较早帧。建议使用 pythontutor.com 进行可视化。

      【讨论】:

        猜你喜欢
        • 2019-10-22
        • 1970-01-01
        • 1970-01-01
        • 2023-01-28
        • 2023-04-09
        • 1970-01-01
        • 2019-06-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多