LeetCode22 括号生成 递归详解

给定n=3,如何生成[’((()))’, ‘(()())’, ‘(())()’, ‘()(())’, ‘()()()’],直接附上代码(python版)

class Solution(object):
    def generateParenthesis(self, n):
        """
        :type n: int
        :rtype: List[str]
        """
        res=[]
        def back(left, right, part):
            if left == right and left == n:
                res.append(part)
                return
            if left

递归代码非常简洁,以至于你会怀疑人生,如此简单的代码为啥就能达到实际效果?
关键就在于①和②一前一后的巧妙设计,其中两个if条件是相互独立的,即刚开始①满足而②不满足,后来①和②都满足,再后来①不满足而②满足。两个back子程序交替执行,因此虽然只有两句话,但递归调用后,就会衍生出很多分支,其中每个分支计算一个括号对。

下面利用最原始的方式(类似单步调试)来理解这个程序,看看结果是如何得到的

嵌套层次 该层要做的事
第0层 back(0, 0, “”)
第1层 back(1, 0, “(”)
第2层 back(2, 0, “((”) ; back(1, 1, “()”)
第3层 back(3, 0, “(((”) ; back(2, 1, “(()”);back(2, 1, “()(”)
第4层 back(3, 1, “((()”) ; back(3, 1, “(()(”);back(2, 2, “(())”);back(3, 1, “()((”);back(2, 2, “()()”)
第5层 back(3, 2, “((())”) ; back(3, 2, “(()()”);back(3, 2, “(())(”);back(3, 2, “()(()”);back(3, 2, “()()(”)
第6层 back(3, 3, “((()))”) ; back(3, 3, “(()())”);back(3, 3, “(())()”);back(3, 3, “()(())”);back(3, 3, “()()()”)
第7层 append+return; append+return;append+return;append+return;append+return

可以看到递归其实就是压栈和弹栈,栈是一种先进后出的数据结构。这里嵌套层次低的是先进的,嵌套层次高的是先出的。嵌套层次低的依赖嵌套层次高的先解决,才能求解。嵌套层次最高的(第7层)直接返回结果。

事实上,嵌套层次低的back函数求解转化为嵌套层次高的back函数求解(表格中应该用箭头标出)。这样看来,递归也可以用树来描述。其中树根是原始问题,内部节点是问题的转化和求解过程,叶子节点是问题的求解结果

那么栈和树有什么联系树根可以看成栈底(表示原始问题),叶子节点看成栈顶(表示能够直接求解的子问题)。树中同一层的节点属于同一个栈元素。纯属个人的一种形象理解 : )

学习递归,我认为有两个阶段,一是能理解递归的执行过程,二是能自己写递归解决问题。本文关注的是第一阶段。

你可能感兴趣的:(LeetCode22 括号生成 递归详解)