Generate Parentheses
来源:互联网 发布:java代码换行符 编辑:程序博客网 时间:2024/06/06 12:44
Generate Parentheses
My SubmissionsTotal Accepted: 57885 Total Submissions: 176392 Difficulty: Medium
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个的所有括号数,按照左括号开始的数目进行枚举,后面插入需
要补充的括号数,代码,如下,但是忽略了一种情况
分析了下此方法较复杂,放弃。
class Solution {public: vector<string> generateParenthesis(int n) {if(!n){ vector<string> ve; return ve;} vector<string> * vectors = new vector<string> [n];for(int ve = 0; ve < n; ve ++){for( int l_num = ve + 1; l_num > 0; l_num --){string str_pre;for( int il_num = 0; il_num < l_num; il_num ++)str_pre.append("(");str_pre.append(")");int sub_num = ve + 1 - l_num;if( !sub_num) //有需要补充的子括号数{string str = str_pre;for( int ir_num = 0; ir_num < l_num -1; ir_num ++)str.append(")");vectors[ve].push_back(str);}else{//插在内部for( vector<string>::iterator ite = vectors[sub_num - 1].begin();ite != vectors[sub_num - 1].end(); ite ++){string str = str_pre;str.append(*ite);for( int ir_num = 0; ir_num < l_num -1; ir_num ++)str.append(")");vectors[ve].push_back(str);}//插在外部for( int wair_num = 1;wair_num <= l_num - 1; wair_num ++ ){for( vector<string>::iterator ite = vectors[sub_num - 1].begin();ite != vectors[sub_num - 1].end(); ite ++){string str = str_pre;for( int ir_num = 0; ir_num < wair_num; ir_num ++)str.append(")");str.append(*ite);for( int ir_num = 0; ir_num < l_num-1-wair_num; ir_num ++)str.append(")");vectors[ve].push_back(str);}}}}}//释放多余内存for(int i = 0; i < n-1; i++)vectors[i].clear();return vectors[n-1]; }};二.网上看了某人的算法,所谓的卡特兰数,代码非常简单,就是建一个二叉树,然后深度搜索,要求每次分支,已经画的左括号数必须大于
右括号数,都画完时返回,代码如下:
class Solution {public: vector<string> generateParenthesis(int n) {vector<string> re;if(!n)return re;string str = ""; generate(re,n,n,str);return re; }void generate(vector<string> &re,int left,int right,string str){if( left == 0 && right == 0)re.push_back(str);if( left > 0)generate( re, left - 1, right, str +"(");if( right > left && right > 0)generate( re, left, right - 1, str + ")");return;}};三. 卡特兰数应用例子:(引用网上例子
入栈出栈顺序问题:给定一个长度为n的不重复数组,求所有可能的入栈出栈顺序。该问题解的个数也是卡特兰数,根据上面的思路,我们也
可以写出一个类似的代码:
- void inoutstack(int in,int out,deque<int> &q,stack<int> &s,deque<int> seq,vector<deque<int>> &result)
- {
- if(!in&&!out)
- {
- result.push_back(q);
- return;
- }
- if(in>0)
- {
- s.push(seq.front());
- seq.pop_front();
- inoutstack(in-1,out,q,s,seq,result);
- seq.push_front(s.top());
- s.pop();
- }
- if(out>0&&in<out)
- {
- q.push_back(s.top());
- s.pop();
- inoutstack(in,out-1,q,s,seq,result);
- s.push(q.back());
- q.pop_back();
- }
- }
栈的次数大于或者等于出栈的次数。在生成括号的问题中,我们利用一个string来保存结果,由于打印左括号时不影响打印右括号,所以无需复
杂的状态恢复。在入栈出栈顺序问题中,由于两次递归调用共享同一个栈和队列,所以我们需要手动恢复其内容。在恢复时,队列会从头部删
除和添加,所以我们采用了deque,它可以在头部添加和删除元素。queue只能在头部删除元素,所以没有采用。
中文:卡特兰数
Catalan数是组合数学中一个常出现在各种计数问题中出现的数列。由以比利时的数学家欧仁·查理·
中文:卡特兰数
Catalan数是组合数学中一个常出现在各种计数问题中出现的数列。由以比利时的数学家欧仁·查理·
卡塔兰 (1814–1894)命名。
原理:
令h(0)=1,h(1)=1,catalan数满足递归式:
h(n)= h(0)*h(n-1) + h(1)*h(n-2) + + h(n-1)h(0) (其中n>=2)
该递推关系的解为:
h(n)=C(2n,n)/(n + 1) (n=1,2,3,)
另类递归式: h(n)=((4*n-2)/(n+1))*h(n-1);
前几项为 (OEIS中的数列A000108): 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796,
原理:
令h(0)=1,h(1)=1,catalan数满足递归式:
h(n)= h(0)*h(n-1) + h(1)*h(n-2) + + h(n-1)h(0) (其中n>=2)
该递推关系的解为:
h(n)=C(2n,n)/(n + 1) (n=1,2,3,)
另类递归式: h(n)=((4*n-2)/(n+1))*h(n-1);
前几项为 (OEIS中的数列A000108): 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796,
58786, 208012, 742900,
2674440, 9694845, 35357670, 129644790, 477638700, 1767263190, 6564120420,
24466267020, 91482563640, 343059613650, 1289904147324, 4861946401452,
应用
我总结了一下,最典型的四类应用:(实质上却都一样,无非是递归等式的应用,就看你能不能
应用
我总结了一下,最典型的四类应用:(实质上却都一样,无非是递归等式的应用,就看你能不能
分解问题写出递归式了)
1.括号化问题。
矩阵链乘: P=a1×a2×a3×……×an,依据乘法结合律,不改变其顺序,只用括号表示成对的
1.括号化问题。
矩阵链乘: P=a1×a2×a3×……×an,依据乘法结合律,不改变其顺序,只用括号表示成对的
乘积,试问有几种括号化的方案?(h(n)种)
2.出栈次序问题。
一个栈(无穷大)的进栈序列为1,2,3,..n,有多少个不同的出栈序列?
类似:
(1)有2n个人排成一行进入剧场。入场费5元。其中只有n个人有一张5元钞票,另外n人只有
2.出栈次序问题。
一个栈(无穷大)的进栈序列为1,2,3,..n,有多少个不同的出栈序列?
类似:
(1)有2n个人排成一行进入剧场。入场费5元。其中只有n个人有一张5元钞票,另外n人只有
10元钞票,剧院无其它钞票,问有多少中方法使得只要有10元的人买票,售票处就有5元的钞票
找零?(将持5元者到达视作将5元入栈,持10元者到达视作使栈中某5元出栈)
(2)在圆上选择2n个点,将这些点成对连接起来,使得所得到的n条线段不相交的方法数。
3.将多边行划分为三角形问题。
将一个凸多边形区域分成三角形区域的方法数?
类似:一位大城市的律师在她住所以北n个街区和以东n个街区处工作。每天她走2n个街区去上班
(2)在圆上选择2n个点,将这些点成对连接起来,使得所得到的n条线段不相交的方法数。
3.将多边行划分为三角形问题。
将一个凸多边形区域分成三角形区域的方法数?
类似:一位大城市的律师在她住所以北n个街区和以东n个街区处工作。每天她走2n个街区去上班
。如果她
从不穿越(但可以碰到)从家到办公室的对角线,那么有多少条可能的道路?
类似:在圆上选择2n个点,将这些点成对连接起来使得所得到的n条线段不相交的方法数?
4.给顶节点组成二叉树的问题。
给定N个节点,能构成多少种形状不同的二叉树?
(一定是二叉树!
先去一个点作为顶点,然后左边依次可以取0至N-1个相对应的,右边是N-1到0个,两两配对相乘,
从不穿越(但可以碰到)从家到办公室的对角线,那么有多少条可能的道路?
类似:在圆上选择2n个点,将这些点成对连接起来使得所得到的n条线段不相交的方法数?
4.给顶节点组成二叉树的问题。
给定N个节点,能构成多少种形状不同的二叉树?
(一定是二叉树!
先去一个点作为顶点,然后左边依次可以取0至N-1个相对应的,右边是N-1到0个,两两配对相乘,
就是h(0)*h(n-1) + h(2)*h(n-2) + + h(n-1)h(0)=h(n))
(能构成h(N)个)
(能构成h(N)个)
0 0
- Generate Parentheses
- Generate Parentheses
- Generate Parentheses
- Generate Parentheses
- Generate Parentheses
- Generate Parentheses
- Generate Parentheses
- Generate Parentheses
- Generate Parentheses
- Generate Parentheses
- Generate Parentheses
- Generate Parentheses
- Generate Parentheses
- Generate Parentheses
- Generate Parentheses
- Generate Parentheses
- Generate Parentheses
- Generate Parentheses
- 给定n个整数,请统计出每个整数出现的次数,按出现次数从多到少的顺序输出。
- Effective C++——条款33(第6章)
- JS的onerror事件
- zxing实现二维码解析和生成
- 查找
- Generate Parentheses
- 设计模式(9):命令模式
- 广义表的head与tail的基本用法
- Struts基本开发搭建步骤-总结
- Debian Stable (Jessie 8.1) 的normal.mod not found
- 简单的区间覆盖问题
- 【HTML】常用跨域技术
- Android开发之路(二)--浅析MVC开发模式
- 设计模式——代理模式