生成括号-回溯的应用

问题:n对括号可以有多少种匹配排列方式?比如两对括号可以有两种:()()和(())

本文就是一个简单的练手:但是重在学习给递归添加约束得到我们预期的结果!

思路:问题可转化为:在一个string中包含两个字符:'('和')',他们出现的次数都为n,并且任何时候'('出现的次数总是>=')'出现的次数。

解决方案(递归):

标志:l: 左括号出现的次数,r:右括号出现的次数,n: 括号对数,s: 存储符合要求的排列字符串,num: 匹配排列种数

步骤:

1.如果r=n,即右括号已出现了n次,则num++,打印s,返回;

2.如果r=l,即左右括号出现次数相等(且<n,这由1知),则在s后面append字符‘(’,并l++,回到1(递归)

3.如果r<l,即右括号出现次数小于左括号,分两种情况

    (1),l=n,即左括号全部出现,则在s后面append字符')',并r++,回到1(递归)

    (2),l<n,则接下来出现的字符可能是'(',也可能是')'。可以:

            在s后append字符‘(’,l++,回到1(递归);然后把s最后的字符'('pop出来,append字符‘)’,l--,r++,再回到1(递归)

代码如下:

 


#include <string>

#include <iostream>

using namespace std;
/*
void parenthesisArrayCount(int l,int r,int n,string s,int& num)

{
    if(r==n)

    {
        num++;
        cout<<s<<endl;
        return;
    }
    if(r==l)
    {
        s.append("(");
        l++;
        parenthesisArrayCount(l,r,n,s,num);
    }
    else//r<l
    {
        if(l==n)
        {

            s.append(")");
            r++;
            parenthesisArrayCount(l,r,n,s,num);
        }
        else
        {
            s.append("(");
            l++;
            parenthesisArrayCount(l,r,n,s,num);
            s.pop_back();
            l--;
            s.append(")");
            r++;
            parenthesisArrayCount(l,r,n,s,num);
        }

    }
    return;
}
*/
int main()

{

    int num=0;
    string s;
    parenthesisArrayCount(0,0,4,s,num);
    s.push_back('a');
    cout << s << endl;
    cout<<"共"<<num<<"种";
//    s.pop_back('a');
    cout << s << endl;
    cout << 0000;


    return 1;

}

代码应该没有问题,但是我在编译的时候提示没有pop_back()这个函数。

二:在递归中添加限制条件,控制递归的运行

1:生成所有中可能

2:找合法输入输出

#include <string>
#include <vector>
#include <iostream>
#include <stdio.h>
using namespace std;
class solution{
public:
    vector<string> generatekuohu(int n){
        
        vector<string> result;
        generate("",n,n,result);
        return result;
    }
private:
    void generate(string item,int left,int right,vector<string> &result)
    {
        if(left==0 && right ==0)
        {
            result.push_back(item);
            return;
        }
        if(left > 0)
        {
           generate(item + '(',left-1,right,result);
        }
        if(left < right)
        {
            generate(item + ')',left,right-1,result);
        }
    }
};


int main()
{
    solution solve;
    vector<string> result = solve.generatekuohu(3);
    for(int i=0;i<result.size();++i)
    printf("%s\n",result[i].c_str());
    
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值