Question:
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:
[
“((()))”,
“(()())”,
“(())()”,
“()(())”,
“()()()”
]
Solution:
class Solution {
public:
vector<string> res ;
typedef struct MTree{
char m_cval;
int m_isum;
int m_ileft;
int m_iright;
MTree* lchild,*rchild;
MTree(char val, int sum, int left ,int right):m_cval(val),m_isum(sum),
m_ileft(left),m_iright(right),lchild(NULL),rchild(NULL){}
} *P_MTree;
void m_malloc(P_MTree pt){
if((pt = (P_MTree)malloc(sizeof(MTree))) == NULL){
cout<<"malloc申请空间失败!"<<endl;
return ;
}
}
void m_vbuild(P_MTree root ){
if((root->m_ileft == 0 && root->m_iright == 0) || root->m_ileft > root->m_iright ){
return ;
}
if(root->m_ileft > 0){
P_MTree lchild = NULL;
m_malloc(lchild);
lchild = new MTree('(',root->m_isum + 1,root->m_ileft - 1,root->m_iright );
root->lchild = lchild;
m_vbuild(lchild);
}
if(root->m_isum > 0){
P_MTree rchild = NULL;
m_malloc(rchild);
rchild = new MTree(')' ,root->m_isum - 1,root->m_ileft ,root->m_iright -1 );
root->rchild = rchild;
m_vbuild(rchild);
}
}
void CLR(P_MTree root,string s){
if(root != NULL){
s += root->m_cval;
CLR(root->lchild,s);
CLR(root->rchild,s);
}
if(root != NULL && root->lchild == NULL && root->rchild == NULL){
res.push_back(s);
}
}
vector<string> generateParenthesis(int n) {
if(n < 1){
return res;
}
P_MTree root = NULL;
m_malloc(root);
root = new MTree('(' , 1 , n - 1 , n);
m_vbuild(root);
string s;
CLR(root,s);
return res;
}
};
总结与延伸:
该问题和组合数学中一个问题相似:
博览会的门票每张50元,每人限购1张,现有10个小朋友排队购票,其中5个小朋友只有100元的钞票1张,另外5个小朋友只有50元的钞票1张,售票员没有准备零钱,那么最多有__种排队方法,使售票员总能找得开钱.
具体解法:解法
解法中42未给出具体过程,根据组合数学相关知识我们知道,
A->B的路径数为(10,5),B的左边和下边都是到达B的前一步,而由B左边到B,路径数位(10,4),不符合条件,则由B下边到B的路径数位(10,5)-(10,4) = 42. 该结论可推广到N ,结果为(2N,N) - (2N,N-1)。我们可以将本题中的‘(’当作+1,‘)’当作-1,要保证任何时刻其和大于等于0即可,所以我们在知道n后可立即算出所有的可能形式。
作者选用树形结构解决(前面所说的数学问题并未利用上,尴尬脸),一是为了复习数据结构,二是实在想不出怎么去利用先前的结论使得代码更加高效,leetcode提交仅击败8%的人,有待优化。