题解 | #括号生成#

括号生成

http://www.nowcoder.com/practice/c9addb265cdf4cdd92c092c655d164ca

题目:括号的生成

描述:给出n对括号,请编写一个函数来生成所有的由n对括号组成的合法组合。

例如,给出n=3,解集为:"((()))", "(()())", "(())()", "()()()", "()(())",

示例1输入:1,返回值:["()"];

示例2输入:2,返回值:["(())","()()"]


解法一:

思路分析:分析题目,我们可以得到,题目的要求为当输入n对括号后,输出所有由n对括号组成的合法组合,这就意味着,当“(”出现的时候,后序必须要有与之配对的“)”存在,首先我们可以设定一个容器对象vector用于存储最终的结果值,设定一个string类型的变量用于存储括号的对数,设定两个变量值分别为i和j,用于监督此刻需要的“(”或者“)”。

其中i和j的值主要分为五种情况,我们一一进行分析(首先定义i和j的值均为n):

第一种:当n为0时,也就是i = j = 0,这时,说明不需要分配括号,直接返回字符串类型即可。

第二种:当i = 0,j > 0时,我们需要添加一个“)”类型,随即将j的值减一,然后进行递归判断。

第三种:当i > 0,j = 0时,我们需要添加一个“(”类型,随即将i的值减一,然后进行递归判断。

第四种:当i的值小于j的值时,我们也可以先添加“(”,令i的值减一后,递归(执行完之后进行回溯判断再次递归),再添加“)”,y - 1后再次进行递归操作。

第五种:当i的值大于等于j时,进行“(”的添加。

实例分析:输入:n =2。

n = 2

新增变量令i = 2,j = 2

容器res

字符串s

第一次

经过判断,属于情况五,递归执行i - 1 = 1,s中添加“(”,递归回溯

第二次

属于情况4,i - 1 = 0,s中添加“(”,s变为“((”,递归回溯

第三次

属于情况2,j - 1 = 1,s中添加“)”,s变为“(()”,递归回溯

第四次

属于情况2,j - 1 = 0,s中添加“)”,s变为“(())”,递归回溯

第五次

属于情况一,将s变量存入容器res中

返回第二次

再次进行判断j = 2,执行第二种,s内变为“()”

第三次

I - 1 = 0,j - 1 = 1,执行第五种,s内放入“(”,s变为“()(”

第四次

执行第二步,s变为“(())”

第五次

执行第一步,将s变量放入res中

返回

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


具体C++代码为: 
class Solution {
public:
    vector<string> generateParenthesis(int n) {
            vector<string> res;//最终存放的容器
            string s = "";//括号保存
            digui(res,n,n,s);//递归执行
            return res;
    }
    
    void digui(vector<string>&res,int i,int j,string s){
        if(i == 0 && j == 0){
            res.push_back(s);//直接存放
            return ;
        }
        if(i == 0 && j > 0){
            digui(res,i,j - 1,s + ")");//添加括号“)”,递归回溯
            return ;
        }
        if(j == 0 && i > 0){
            digui(res,i - 1,j,s + "(");//添加括号“(”,递归回溯
            return ;
        } 
        if(i < j){
            digui(res,i - 1,j,s + "(");//添加括号“(”,递归回溯
            digui(res,i,j - 1,s + ")");//添加括号“)”,递归回溯
            return ;
        }
        if(i >= j){
            digui(res,i - 1,j,s + "(");//添加括号“(”,递归回溯
            return ;
        }
    }
};

该算法需要不断的进行回溯,总体比较复杂,当i和j的值都为0的时候,才能结束循环,整体时间复杂度相当复杂,空间复杂度为O(N)。

解法二:

思路分析:在上述解法当中,我们发现在括号没有完全匹配之前,右括号的使用数量应当小于左括号的使用数量。根据这一点直接使用递归完成括号的生成。

具体python代码为:


#
#
# @param n int整型
# @return string字符串一维数组
#
class Solution:
  def generateParenthesis(self, n: int):
      res = []#保存对象
      cur_str = ''#储存括号
      def dfs(cur_str, left, right):  #左括号或者右括号还可以使用的个数
          if left == 0 and right == 0:
              res.append(cur_str)
              return
          if right < left: #生成括号的过程中,右括号使用的个数是不能多于左括号使用的个数的 return if left > 0:
              dfs(cur_str + '(', left - 1, right)
          if right > 0:
              dfs(cur_str + ')', left, right - 1)
 
      dfs(cur_str, n, n)
      return res


编写python代码较为舒展,在计算的过程中应该始终坚持括号的优先原则,时间复杂度为O(N),空间复杂度为O(N)。



算法自然分析 文章被收录于专栏

在解决问题的同时,不断与人交流学习,通过牛客各式各样的题目,学习分享。

全部评论
题解一中有种情况(j==0 && i>0)是不可能出现的,若出现就是错了,谁家的合法括号是以左括号结尾?
2 回复 分享
发布于 2021-11-01 17:01
python代码 括号写反了,改过来就行
2 回复 分享
发布于 2021-11-29 15:51
解法二的python代码有问题
1 回复 分享
发布于 2021-10-31 23:12
if r>l: dfs(cur+')',l,r-1) if l>0: dfs(cur+'(',l-1,r)
1 回复 分享
发布于 2022-04-07 20:52
python 解法写错了
点赞 回复 分享
发布于 2022-11-11 20:50 广东

相关推荐

去B座二楼砸水泥地:不过也可以理解,这种应该没参加过秋招
点赞 评论 收藏
分享
10-27 17:26
东北大学 Java
点赞 评论 收藏
分享
11 5 评论
分享
牛客网
牛客企业服务