首页 > 代码库 > LeetCode: Generate Parentheses
LeetCode: 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:
"((()))", "(()())", "(())()", "()(())", "()()()"
思路:
主要参考了这里http://blog.csdn.net/yutianzuijin/article/details/13161721
之前想法受了前一个问题Valid Parentheses的影响,一直考虑进栈出栈乱七八糟的东西,绕了弯路,最后发现没有抓住问题的实质。括号都是成对出现的,所以序列总长度为2n,生成的字符串规的则其实很简单:该字符串从起始位置到任意一个位置的字串中,"(" 的个数要大于等于 ")"的个数。因此,打印的方法如下:假设在位置k我们还剩余left个左括号和right个右括号,如果left>0,则我们可以直接打印左括号,而不违背规则。能否打印右括号,我们还必须验证left和right的值是否满足规则,如果left>=right,则我们不能打印右括号,因为打印会违背合法排列的规则,否则可以打印右括号。如果left和right均为零,则说明我们已经完成一个合法排列,可以将其打印出来。用递归方法实现。
代码几乎是复制过来的,主要是这种思路很清晰,代码也非常简洁,并且为类似的问题提供一般性的思路。
后来看到原来个问题的所有合法解的个数之和叫做卡特兰(Catalan)数。具体介绍和一些应用可以看这里http://www.cppblog.com/MiYu/archive/2010/08/07/122573.html
《编程之美》中也有类似的“买票找零”问题,只不过比较靠后,还没看到(其实根本没看几页,真是汗颜)。略微不同的是那个问题是要求解总个数,而本题是要画出所有可能的路径。
代码:
1 class Solution { 2 public: 3 vector<string> generateParenthesis(int n) { 4 string s=""; 5 vector<string> res; 6 generate(n,n,s,res); 7 return res; 8 } 9 void generate(int left,int right,string s,vector<string> &res)10 {11 if(left==0&&right==0)12 {13 res.push_back(s);14 }15 if(left>0)16 {17 generate(left-1,right,s+"(",res);18 }19 if(right>0&&right>left)20 {21 generate(left,right-1,s+")",res);22 }23 }24 };