首页 > 代码库 > 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 };