来自北大算法课的Leetcode题解:22. 括号生成

代码仓库Github | Leetcode solutions @doubleZ0108 from Peking University.

  • 解法1(超时):看数据规模不大,本来想暴力解。首先将n个(和n个)加入到数组中,然后调用库函数itertools.permutations()进行全排列,并通过集合set()去重,最后再依次判断每个可能的组合是否合法,可以根据20题的算法用栈来判断括号是否匹配
  • 解法2(T60% S90%):又是经典的深搜(携带参数递归),递归参数设定为cur代表当前做到的下标位置,li代表这一种情况的括号组成,还有两个参数leftCountrightCount代表当前位置之前左右括号的数量。
    • 初始:cur=1(因为第一个必须是(),li的首元素是( 其余为空,leftCount=1rightCount=0
    • 终止条件:如果leftCountrightCount大于n则直接返回,当前解不可能(事实上只判断leftCount就好,rightCount不可能大于n);如果cur指到最后位置2n了就可以将当前li转换为字符串加入结果中了
    • 递归:如果leftCount>rightCount,代表之前肯定有一个(,则可以把当前位置放一个)并递归;否则当前位置只能放(再递归
class Solution(object):
    def generateParenthesis(self, n):
        """
        :type n: int
        :rtype: List[str]
        """
        res = []

        def gen(cur, li, leftCount, rightCount):
            if leftCount>n: return
            if cur == 2*n:
                res.append("".join(li))
                return
            if leftCount > rightCount:
                li[cur] = ')'
                gen(cur+1, li, leftCount, rightCount+1)
            li[cur] = '('
            gen(cur+1, li, leftCount+1, rightCount)     
            
        li = ['' for _ in range(2*n)]
        li[0] = '('
        gen(1, li, 1, 0)
        return res


    def otherSolution(self, n):
        # 解法1 超时
        def isValid(item):
            stack = []
            for s in item:
                if s == '(': stack.append(s)
                else:
                    if len(stack)<=0: return False
                    if stack.pop() != '(': return False
            return stack==[]

        li = []
        for i in range(n): 
            li.append('(')
            li.append(')')

        from itertools import permutations
        li = list(set(permutations(li)))

        res = []
        for item in li:
            if isValid(item): res.append("".join(item))
        return res
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

doubleZ0108

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值