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%的人,有待優化。