22. 括号生成

https://leetcode-cn.com/problems/generate-parentheses/

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

例如,给出 n = 3,生成结果为:

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

 

这种括号的题目一般都是dfs,当前放左括号或者放右括号。注意左括号的累计计数不能少于右括号,不然就不是有效括号了,比如(()))。

 1 class Solution {
 2 public:
 3     vector<string> generateParenthesis(int n) {
 4         if(n<=0){return {};}
 5         vector<string> res;
 6         string cur="";
 7         dfs(res,cur,0,0,n);
 8         return res;
 9     }
10     void dfs(vector<string>& res,string& cur,int cur_le,int cur_ri,int n){
11         if(cur_len or cur_ri>n){
12             return;
13         }
14         if(cur_le==n and cur_ri==n){
15             res.push_back(cur);
16             return;
17         }
18         cur.push_back('(');
19         dfs(res,cur,cur_le+1,cur_ri,n);
20         cur.back()=')';
21         dfs(res,cur,cur_le,cur_ri+1,n);
22         cur.pop_back();//注意这里要pop_back()!!!!!!
23     }
24 };

 还有一种动态规划法。

从i-1对括号的结果加一对括号,就得到了i对括号的结果。

贴一个说的比较好的题解:

当我们清楚所有 i
它一定是一个左括号,那么它可以和它对应的右括号组成一组完整的括号 "( )",我们认为这一组是相比 n-1 增加进来的括号。

那么,剩下 n-1 组括号有可能在哪呢?

【这里是重点,请着重理解】

剩下的括号要么在这一组新增的括号内部,要么在这一组新增括号的外部(右侧)。

既然知道了 i

"(" + 【i=p时所有括号的排列组合】 + ")" + 【i=q时所有括号的排列组合】

其中 p + q = n-1,且 p q 均为非负整数。

事实上,当上述 p 从 0 取到 n-1,q 从 n-1 取到 0 后,所有情况就遍历完了。

注:上述遍历是没有重复情况出现的,即当 (p1,q1)≠(p2,q2) 时,按上述方式取的括号组合一定不同。

作者:yuyu-13

 1 class Solution {
 2 public:
 3     vector<string> generateParenthesis(int n) {
 4         if(n==1){
 5             return {"()"};
 6         }
 7         vectorstring>> dp={{""},{"()"}};//初始dp
 8         for(int i=2;i<=n;++i){
 9             dp.push_back({});
10             for(int j=0;jj){
11                 string p="";
12                 for(string s1:dp[j]){
13                     for(string s2:dp[i-j-1]){
14                         dp.back().push_back('('+s1+')'+s2);
15                     }
16                 }
17             }
18         }
19         return dp.back();
20     }
21 };

 

你可能感兴趣的:(22. 括号生成)