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<n: #第①处
                back(left + 1, right, part + '(')
            if right<left: #第②处
                back(left, right + 1, part + ')')
        back(0, 0, "")
        return res

s=Solution()
print(s.generateParenthesis(3))

递归代码非常简洁,以至于你会怀疑人生,如此简单的代码为啥就能达到实际效果?
关键就在于①和②一前一后的巧妙设计,其中两个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函数求解(表格中应该用箭头标出)。这样看来,递归也可以用树来描述。其中树根是原始问题,内部节点是问题的转化和求解过程,叶子节点是问题的求解结果

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

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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值