LeetCode 22. Generate Parentheses(括号生成)

原题

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

For example, given n = 3, a solution set is:

题目:
给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。

Example:

[
  "((()))",
  "(()())",
  "(())()",
  "()(())",
  "()()()"
]

Reference solution

思路分析:
两题差别有两个 ,一个是生成括号只包括小括号 ‘()’ ,另一个是逻辑相逆 ,这里是要生成有效的括号序列 。一个很关键的问题就出来了 ,什么样的序列有效呢 ?当然可以参考第 20 题 ,但是这里更简单只有一种小括号字符 。分析发现只要左右小括号数量相等 ,生成的括号序列就有效 。

这里提供两种思路 ,一个是暴力法 ,生成所有的括号序列 ,再判断是否有效 ;一个是递归生成有效的序列方法 。

思路一 :
这里只有 ‘( ’ 和 ‘ )’ 两种字符可能 ,暴力生成所有字符串序列有 2的2n次方种可能 。根据自己的思维 ,小詹分成两个关键点讲解 ,一个是如何判断有效 ,一个是如何暴力生成所有字符串 。判断有效与否只需要当生成字符串序列长度为 2n 时判断是否左右括号数量相等 ;生成所有字符串则是利用递归思路 ,而只有左右括号两种可能 ,那么问题就简单了 ,见下代码 :

class Solution(object):
    def generateParenthesis(self, n):
        #子函数 ,生成括号序列 ,递归思路哦
        def generate(A = []):
            if len(A) == 2*n: #如果生成的括号序列长度为2n,就判断是否有效
                if valid(A):
                    ans.append("".join(A)) #有效括号序列添加进ans
            else: 
            #不够长度则通过递归调用generate生成,如果是无效则将上一个括号字符pop出,并继续generate
                A.append('(')
                generate(A)
                A.pop()
                A.append(')')
                generate(A)
                A.pop()
        #判断生成的长度为2n括号序列是否有效
        def valid(A):
            bal = 0
            for c in A:
                if c == '(': bal += 1
                else: bal -= 1
                if bal < 0: return False
            return bal == 0
        #定义空列表ans存储,通过调用generate执行直到所有结果都判断了一遍结束
        ans = []
        generate()
        return ans

递归过程:
在这里插入图片描述

思路二:
与思路一不同 ,只有在我们知道序列仍然保持有效时才添加 ‘(’ or ‘)’ ,n 对括号意味着左右括号数量都为 n ,所以子函数可以以当前括号序列+左括号数量+右括号数量为参数 ,利用递归生成所有有效的括号序列 !注意 ,这里生成的不在是所有的序列 ,而是通过控制左右括号数量生成有效序列 。具体代码如下 :

class Solution:
    def generateParenthesis(self, n):
        """
        :type n: int
        :rtype: List[str]
        """
        
        res = []
        self.genParenthesis(res, "", n, n)
        return res
    
    def genParenthesis(self, res, current, left, right):
        if left == 0 and right == 0:
            res.append(current)
        if left > 0:
            self.genParenthesis(res, current+'(', left-1, right)
        if left < right:
            self.genParenthesis(res, current+')', left, right-1) 

递归过程:

在这里插入图片描述

反思:

  1. 解决这道题时候最大的障碍就是不知道如何理解递归,参考上面两图分析,寻找递归规律。
  2. 注意string合并到list方法 ans.append("".join(A)) #有效括号序列添加进ans

猜你喜欢

转载自blog.csdn.net/Dby_freedom/article/details/82840643
今日推荐