22.括号生成

难度:中等

目录

一、问题描述

二、思路

1、解题思路

三、解题

1、代码实现

2、时间复杂度 and 空间复杂度

四、总结 


一、问题描述

这里直接采用LeetCode上面的描述。

        数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

下面给出示例:

提示:

  • 1 <= n <= 8

二、思路

1、解题思路

        这里题目就是给我们 n' ( '' ) ' ,让我们进行排列组合,保留符合括号匹配的答案,因此我们可以用 DFS 排列出所有的排列组合,但是其中有不符合要求的答案,因此我们要进行 剪枝 操作,将不符合题目要求的枝 减去,这样 DFS 到最终 只留下符合要求的 答案。

因此我们可以开始观察

当( n == 1 ):

 

        我们可以看到上图,要满足要求题目要求,必须先保存 ' ( ',即 左括号数量必须 >= 右括号数量 。我们可以知道结束 DFS 的条件为: 左括号 == n && 右括号 == n

当( n == 2 ):

         观察上图,我们可以看到符合要求的分支都是:

  1. 左括号数量 >= 右括号数量
  2. 当左右括号数量相等时,优先 添加 ' ( ',才能继续满足 条件1。 

综上所述,我们可以完成 DFS剪枝 的条件。

        每次递归都往 str 中添加一个括号,并且更新 左括号 右括号 的数量,再进行下一次递归,直至左右括号都达到最大数量停止 递归 开始 回溯。

三、解题

1、代码实现

class Solution {
public: 
    // n 为一对括号的数量(左括号和右括号的最大数量),left 为左括号的数量,right 为右括号的数量,str为递归的字符串
    void DFS(int n, int left, int right, string str){
        //递归停止条件:满足要求,将答案保存
        if(left == n && right == n){
            ans.push_back(str);
        }
        //不满足停止递归条件 即 进行剪枝操作,只保留符合要求的树枝
        else{
            //当左括号 数量小于 左括号的最大数量时,可以添加 '('
            if(left < n){
                DFS(n,left+1,right,str+'(');
            }
            //右括号数量小于左括号数量时 ,可以添加 ')'
            if(right < left){
                DFS(n,left,right+1,str+')');
            }
        }
    }
    vector<string> generateParenthesis(int n) {
        string str = "";
        DFS(n, 0, 0, str);
        return ans;
    }
private:
vector<string> ans;
};

 

 

2、时间复杂度 and 空间复杂度

时间复杂度:O(\frac{4^n}{\sqrt{n}})

空间复杂度:O(n)

四、总结 

        这一题对我来说还是比较难的,刚开始没想到用的 DFS 后来看了题解恍然大悟,还能有这种解法,刚开始的思路是:将所有的有效组合全部排列出来,再从排列组合中去选取满足题目要求的 答案保存下来。

        以后碰到类似的题,要在排列组合中 将不符合要求的筛选掉,使用的就是 DFS + 剪枝 的操作,不断的减去不符合要求的枝叶,直至结束递归 剩下的就是符合要求的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

_Alkaid_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值