leetcode-Generate Parentheses

本文介绍了一种生成合法括号组合的算法实现,通过构建树形结构递归地生成所有可能的括号序列,并确保任何时候左括号数量不小于右括号数量。此外,文章还探讨了一个与组合数学相关的问题,即10个小朋友购票的不同排列方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值