[C++]LeetCode: 84 Generate Parentheses (卡特兰数)

来源:互联网 发布:软件开发成本核算 编辑:程序博客网 时间:2024/05/01 02:43

题目:

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:

"((()))", "(()())", "(())()", "()(())", "()()()"

思路:

所有组合的个数C是一个卡特兰数。


用更小的C去求解组合的所有可能性。我们来看下具体如何解决。一般采用递归的方法,这样可以归结为子问题去解决。在每个递归函数中记录左括号的数量和可以加入的右括号的数量,然后每次都有两种选择,一个是放入左括号,一个是放入右括号。不过这些是有附加条件的,左括号的数量要大于0,可以加入的右括号的数量也要大于0(保证结果是合法的)。递归结束条件是,左右括号数量都为0。

Attention:

1. 设计巧妙,要保证结果的合法性,必须保证左括号的数量>0 (添加左括号);采用可被添加的右括号数量(左括号数量>右括号数量)

<span style="font-size:14px;">//根据剩余左括号的数量,以及可以添加的右括号的数量,来遍历所有的可能, 只要两者不为零,都会进行两次选择(遍历两个分叉)        if(m > 0) { generateParenthesis_helper(ret, str + ")", n, m-1); }        if(n > 0) { generateParenthesis_helper(ret, str + "(", n-1, m+1); }</span>
2. 这道题准确来讲,不涉及回溯的问题,我们只是遍历一个合法的二叉树(符合括号构成原则),并且打印所有的结果。所以不需要pop_back()添加进去的结果。因为我们是带着条件去go_deeper的,并且合法情况下,总是有两个选择。

可以试着画一个n = 2的遍历结果来加深理解。


复杂度:O(结果的数量)。 

AC Code:

<span style="font-size:14px;">class Solution {public:    vector<string> generateParenthesis(int n) {        vector<string> ret;        if(n <= 0) return ret;        generateParenthesis_helper(ret, "", n, 0);        return ret;    }private:    void generateParenthesis_helper(vector<string>& ret, string str, int n, int m)    {        if(n == 0 && m == 0)        {            ret.push_back(str);            return;        }                //根据剩余左括号的数量,以及可以添加的右括号的数量,来遍历所有的可能, 只要两者不为零,都会进行两次选择(遍历两个分叉)        if(m > 0) { generateParenthesis_helper(ret, str + ")", n, m-1); }        if(n > 0) { generateParenthesis_helper(ret, str + "(", n-1, m+1); }    }};</span>



0 0
原创粉丝点击