leetcode-Generate Parentheses

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章