[python]leetcode(22). Generate Parentheses

本文介绍了两种生成合法括号组合的方法:回溯法与动态规划。回溯法通过递归构造所有可能的括号组合,并确保每一步都符合合法性;动态规划则利用递推公式f(n) = (f(i))f(n-1-i),通过已知的f(0)到f(n-1)来推导出f(n)。

problem

Given n pairs of parentheses, write a function to generate all
combinations of well-formed parentheses.

solution1-回溯法

参考这篇博客的模板,我们可以把括号生成的问题考虑成一颗二叉树遍历问题,对这棵树进行遍历回溯。

class Solution(object):
    def backtrack(self, res, tmpstr, left, right, n):
        if len(tmpstr) == n*2:
            res.append(tmpstr[:])
        else:
            if left < n:
                self.backtrack(res, tmpstr + '(', left + 1, right, n)
            if right < left:
                self.backtrack(res, tmpstr + ')', left, right + 1, n)


    def generateParenthesis(self, n):
        res = []
        self.backtrack(res, '', 0, 0, n)
        return res

这个算法关键是考虑好分支限界问题,分别是

  1. 如果当前左括号数量小于n,则可以继续添加’(‘
  2. 如果当前右括号数量小于左括号数量,则可以继续添加’)’

另外一个和模板不同的地方是之前是操作的list(可变对象),所以直接append和pop很方便、节约内存,而这里的str不可变,所以我们只能传入副本,对原来的tmpstr不进行修改,也就不需要pop了。

solution2-动态规划解法

如何通过f(1)…f(n-1)推出f(n),及如何写出递推方程?

f(n)比f(n-1)多一对括号,因为第一个位置肯定是左括号’(‘,要想放入右括号后括号仍然匹配,就要新加入的左右括号之间有i对匹配的括号,右边有n-i-1对。

f(0): “”

f(1): “(“f(0)”)”

f(2): “(“f(0)”)”f(1), “(“f(1)”)”

f(3): “(“f(0)”)”f(2), “(“f(1)”)”f(1), “(“f(2)”)”

So f(n) = “(“f(0)”)”f(n-1) , “(“f(1)”)”f(n-2) “(“f(2)”)”f(n-3) … “(“f(i)”)”f(n-1-i) … “(f(n-1)”)”

因为,这样算法推出的字符串都满足要求,且f(n)中的匹配形式一定可以拆成这样的形式’(f(i))f(n-i-1)’,所以这个递推方程是正确的。

总结

这种满足一定条件的,序列生成问题一般都可以用回溯法解决。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值